Descriptive analysis

2022-09-26

Import data

serology <- read_csv("./01_data/raw/FFI.peru.serology.kmeans2.csv") %>%
  rename(ffi_is_code = Codigo) %>%
  select(-1)
## New names:
## Rows: 3996 Columns: 25
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (6): hf, upch_ei_fecha, District, Communities, upch_ei_sexo, Location dbl (19):
## ...1, Codigo, age, Plate, pfmsp119, pfama1, gexp18, glurpr2, rh220...
## ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## • `` -> `...1`
ffi_individual <- read_csv("./01_data/raw/individuals_result_share_072022.csv")
## Warning: One or more parsing issues, see `problems()` for details
## Rows: 4000 Columns: 147
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (31): ffi_is_code, ffi_is_community, ffi_is_district, ffi_is_health_fac...
## dbl  (99): ffi_is_sex, ffi_is_pregnancy, ffi_is_time_pregnancy, ffi_is_age, ...
## lgl   (5): ffi_is_trip_last_symp_other_othr, ffi_micro_result_specie, ffi_mi...
## date  (8): ffi_is_date, ffi_is_birth_date, ffi_is_antimal_drug_use_date, ffi...
## time  (4): ffi_is_time_bath, ffi_is_time_wakeup, ffi_is_time_sleep, ffi_is_t...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ffi_household <- read_csv("./01_data/raw/household_gps_share_072022.csv")
## Rows: 980 Columns: 103
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (22): ffi_h_code, ffi_h_district, ffi_h_community, ffi_h_health_facilit...
## dbl  (77): ffi_h_tot_family, ffi_h_tot_rooms, ffi_h_tot_beds, ffi_h_mti, ffi...
## lgl   (2): ffi_h_material_floor_othr, ffi_h_fuel_kitchen_othr
## dttm  (1): ffi_gps_time
## date  (1): ffi_h_date
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
data_2000_2019 <- read_csv("./01_data/raw/Data_FFI_2000_2019_20212405.csv")
## Rows: 31795 Columns: 23
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr   (6): Health Facility Name, Institution Type, Province, District, Facil...
## dbl  (16): HFUID, RENAESID, Facility Network, Facility sub-network, Latitude...
## date  (1): Date by month
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
data_2020_2021 <- read_csv("./01_data/raw/Data_FFI_2020_2021_20210629.csv")
## Rows: 1751 Columns: 23
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr   (6): Health Facility Name, Institution Type, Province, District, Facil...
## dbl  (16): HFUID, RENAESID, Facility Network, Facility sub-network, Latitude...
## date  (1): Date by month
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
poblacion <- readRDS("./01_data/raw/poblacion_inei_2017.rds")

Format data

ffi_total <- ffi_individual %>%
  full_join(
    serology %>%
      mutate(
        ffi_is_code = paste0(0, ffi_is_code)
      ),
    by = "ffi_is_code"
  )

ffi_total <- ffi_total %>%
  mutate(
    age_cat = case_when(
      ffi_is_age_fixed >= 70 ~ "[70+)",
      ffi_is_age_fixed >= 60 ~ "[60-70)",
      ffi_is_age_fixed >= 50 ~ "[50-60)",
      ffi_is_age_fixed >= 40 ~ "[40-50)",
      ffi_is_age_fixed >= 30 ~ "[30-40)",
      ffi_is_age_fixed >= 20 ~ "[20-30)",
      ffi_is_age_fixed >= 10 ~ "[10-20)",
      ffi_is_age_fixed >= 0 ~ "[0-10)"
    ),
    age_cat = factor(age_cat),
    age_code = case_when(
      age_cat == "[70+)" ~ 8,
      age_cat == "[60-70)" ~ 7,
      age_cat == "[50-60)" ~ 6,
      age_cat == "[40-50)" ~ 5,
      age_cat == "[30-40)" ~ 4,
      age_cat == "[20-30)" ~ 3,
      age_cat == "[10-20)" ~ 2,
      age_cat == "[0-10)" ~ 1,
    ),
    gender = factor(
      ffi_is_sex,
      labels = c("Male", "Female")
    ),
    ffi_is_malaria = factor(
      ffi_is_malaria,
      labels = c("No", "Yes", "Don't Know / No Answer")
    ),
    across(
      c(pf_recent:pv_historic),
      ~ factor(., labels = c("Negative", "Positive"))
    ),
    across(
      c(
        ffi_is_fever_month,
        ffi_is_antimal_drug_use, 
        ffi_is_mosq_net
      ),
      ~ factor(., labels = c("No", "Yes"))
    ),
    ffi_is_trip_month = factor(
      ffi_is_trip_month,
      labels = c("No", "Yes", "Don't Know/No Answer")
    ),
    ffi_is_mal_lifetime = factor(
      ffi_is_mal_lifetime,
      labels = c(
        "1 to 3 times",
        "3 to 7 times",
        "More than 7 times"
      )
    ),
    ffi_is_place_shower = factor(
      ffi_is_place_shower,
      labels = c(
        "Bathroom inside the dwelling",
        "Bathroom outside the dwelling",
        "In the countryside/river",
        "Other"
      )
    ),
    education_level = case_when(
      ffi_is_inst_level %in% 0 ~ "No schooling", 
      ffi_is_inst_level %in% 1:2 ~ "Primary school",
      ffi_is_inst_level %in% 3:4 ~ "Secondary school",
      ffi_is_inst_level %in% 5:6 ~ "Higher education"
    ),
    education_level = fct_relevel(education_level, "No schooling",
                                  "Primary school",
                                  "Secondary school"),
    economic_activities = factor(ffi_is_main_econ_act,
                                 labels = c("Day labourer",
                                            "Wood extractor",
                                            "Fisherman",
                                            "Livestock farmer",
                                            "Farmer",
                                            "Trader",
                                            "Housewife",
                                            "Student",
                                            "Motorcycle taxi driver",
                                            "None",
                                            "Other")),
    pv_exposure = case_when(
      pv_recent == "Negative" & pv_historic == "Negative" ~ "Negative",
      is.na(pv_recent) & is.na(pv_historic) ~ NA_character_,
      TRUE ~ "Positive"
    ),
    pf_exposure = case_when(
      pf_recent == "Negative" & pf_historic == "Negative" ~ "Negative",
      is.na(pf_recent) & is.na(pf_historic) ~ NA_character_,
      TRUE ~ "Positive"
    ),
    recent_exposure = case_when(
      pv_recent == "Negative" & pf_recent == "Negative" ~ "Negative",
      is.na(pv_recent) & is.na(pf_recent) ~ NA_character_,
      TRUE ~ "Positive"
    ),
    historical_exposure = case_when(
      pv_historic == "Negative" & pf_historic == "Negative" ~ "Negative",
      is.na(pv_historic) & is.na(pf_historic) ~ NA_character_,
      TRUE ~ "Positive"
    ),
    only_pv_exposure = case_when(
      pv_exposure == "Positive" & pf_exposure == "Negative" ~ "Positive", 
      TRUE ~ "Negative"
    ),
    only_pf_exposure = case_when(
      pf_exposure == "Positive" & pv_exposure == "Negative" ~ "Positive", 
      TRUE ~ "Negative"
    ),
    pv_pf_exposure = case_when(
      pv_exposure == "Positive" & pf_exposure == "Positive" ~ "Positive",
      TRUE ~ "Negative"
    ),
    freedom_malaria = case_when(
      pv_exposure == "Negative" & pf_exposure == "Negative" ~ "Positive", 
      TRUE ~ "Negative"
    ),
    only_pv_recent = case_when(
      pv_recent == "Positive" & pf_recent == "Negative" ~ "Positive", 
      TRUE ~ "Negative"
    ),
    only_pf_recent = case_when(
      pf_recent == "Positive" & pv_recent == "Negative" ~ "Positive", 
      TRUE ~ "Negative"
    ),
    pv_pf_recent = case_when(
      pv_recent == "Positive" & pf_recent == "Positive" ~ "Positive",
      TRUE ~ "Negative"
    ),
    freedom_malaria_recent = case_when(
      pv_recent == "Negative" & pf_recent == "Negative" ~ "Positive", 
      TRUE ~ "Negative"
    ),
    only_pv_historic = case_when(
      pv_historic == "Positive" & pf_historic == "Negative" ~ "Positive", 
      TRUE ~ "Negative"
    ),
    only_pf_historic = case_when(
      pf_historic == "Positive" & pv_historic == "Negative" ~ "Positive", 
      TRUE ~ "Negative"
    ),
    pv_pf_historic = case_when(
      pv_historic == "Positive" & pf_historic == "Positive" ~ "Positive",
      TRUE ~ "Negative"
    ),
    freedom_malaria_historic = case_when(
      pv_historic == "Negative" & pf_historic == "Negative" ~ "Positive", 
      TRUE ~ "Negative"
    ),
    across(c(pv_exposure:freedom_malaria_historic), factor)
  )

labelled::var_label(ffi_total) <- list(
  ffi_is_district = "Districs",
  gender = "Gender",
  age_cat = "Age",
  education_level = "Education Level",
  economic_activities = "Economic Activities",
  pf_recent = "Recent P. Falciparum",
  pf_historic = "Historical P. Falciparum",
  pv_recent = "Recent P. Vivax",
  pv_historic = "Historical P. Vivax",
  pv_exposure = "P. Vivax Exposure",
  pf_exposure = "P. Falciparum Exposure"
)
saveRDS(ffi_total, 
        file = "01_data/processed/ffi_total.rds")

Table descriptive

library(gtsummary)

fisher.test.simulate.p.values <- function(data, variable, by, ...) {
  result <- list()
  test_results <- stats::fisher.test(data[[variable]], data[[by]], simulate.p.value = TRUE)
  result$p <- test_results$p.value
  result$test <- test_results$method
  result
}

Table for district

table_1 <- ffi_total %>%
  select(
    ffi_is_district,
    gender,
    age_cat,
    education_level,
    economic_activities,
    pf_recent:pv_historic
  ) %>%
  tbl_summary(
    by = "ffi_is_district",
    missing_text = "Missing"
  ) %>%
  add_n() %>%
  add_overall() %>%
  add_p(
     test = list(all_categorical() ~ "fisher.test.simulate.p.values")
  ) %>% 
  bold_p() %>%
  modify_header(label = "**Variable**") %>%
  bold_labels()
  
table1
## # A tibble: 6 × 4
##   country      year  cases population
##   <chr>       <int>  <int>      <int>
## 1 Afghanistan  1999    745   19987071
## 2 Afghanistan  2000   2666   20595360
## 3 Brazil       1999  37737  172006362
## 4 Brazil       2000  80488  174504898
## 5 China        1999 212258 1272915272
## 6 China        2000 213766 1280428583
table_1 %>%
  as_flex_table() %>%
  flextable::save_as_docx(path = "./02_output/reports/table1.docx")

Table for Plasmodium

 table2 <- ffi_total %>%
   select(
     gender,
     age_cat,
     education_level,
     economic_activities,
     pf_exposure,
     pv_exposure
   ) %>%
   drop_na(pf_exposure, pv_exposure) %>%
   pivot_longer(
     cols = pv_exposure:pf_exposure,
     names_to = "exposure",
     values_to = "result_exposure"
   ) %>%
   mutate(
    exposure = case_when(
      exposure == "pv_exposure" ~ "P. Vivax Exposure",
      exposure == "pf_exposure" ~ "P. Falciparum Exposure"
    )
   ) %>%
   tbl_strata(
    strata = exposure,
    .tbl_fun =
      ~ .x %>%
          tbl_summary(
            by = result_exposure,
            missing_text = "Missing"
          ) %>%
          add_p(
            test = list(all_categorical() ~ "fisher.test.simulate.p.values")
          ) %>%
          bold_p() %>%
          modify_header(label = "**Variable**") %>%
          bold_labels() 
   ) 

table2_overall <- ffi_total %>%
  select(
    gender,
    age_cat,
    education_level,
    economic_activities,
    pf_exposure,
    pv_exposure
  ) %>%
  drop_na(pf_exposure, pv_exposure) %>%
  tbl_summary(
    missing_text = "Missing"
  ) %>%
  modify_header(
    label = "**Variable**"
  ) %>%
  bold_labels() %>%
  modify_spanning_header(stat_0 ~ "**Overall**")

table2 <- tbl_merge(
  tbls = list(table2, table2_overall),
  tab_spanner = FALSE
)

table2
Variable P. Falciparum Exposure P. Vivax Exposure Overall
Negative, N = 3,8971 Positive, N = 991 p-value2 Negative, N = 3,6831 Positive, N = 3131 p-value2 N = 3,9961
Gender 0.083 <0.001
Male 2,007 (52%) 60 (61%) 1,839 (50%) 228 (73%) 2,067 (52%)
Female 1,890 (48%) 39 (39%) 1,844 (50%) 85 (27%) 1,929 (48%)
Age 0.020 <0.001
[0-10) 1,075 (28%) 15 (15%) 1,089 (30%) 1 (0.3%) 1,090 (27%)
[10-20) 905 (23%) 19 (19%) 913 (25%) 11 (3.5%) 924 (23%)
[20-30) 372 (9.6%) 8 (8.2%) 360 (9.8%) 20 (6.4%) 380 (9.5%)
[30-40) 423 (11%) 11 (11%) 380 (10%) 54 (17%) 434 (11%)
[40-50) 350 (9.0%) 13 (13%) 300 (8.2%) 63 (20%) 363 (9.1%)
[50-60) 332 (8.5%) 14 (14%) 285 (7.8%) 61 (20%) 346 (8.7%)
[60-70) 212 (5.5%) 8 (8.2%) 177 (4.8%) 43 (14%) 220 (5.5%)
[70+) 219 (5.6%) 10 (10%) 170 (4.6%) 59 (19%) 229 (5.7%)
Missing 9 1 9 1 10
Education Level 0.020 <0.001
No schooling 754 (19%) 10 (10%) 743 (20%) 21 (6.7%) 764 (19%)
Primary school 1,866 (48%) 59 (60%) 1,723 (47%) 202 (65%) 1,925 (48%)
Secondary school 1,176 (30%) 30 (30%) 1,117 (30%) 89 (28%) 1,206 (30%)
Higher education 98 (2.5%) 0 (0%) 97 (2.6%) 1 (0.3%) 98 (2.5%)
Missing 3 0 3 0 3
Economic Activities <0.001 <0.001
Day labourer 854 (22%) 13 (13%) 847 (23%) 20 (6.4%) 867 (22%)
Wood extractor 30 (0.8%) 3 (3.1%) 27 (0.7%) 6 (1.9%) 33 (0.8%)
Fisherman 25 (0.6%) 2 (2.0%) 20 (0.5%) 7 (2.2%) 27 (0.7%)
Livestock farmer 72 (1.8%) 3 (3.1%) 62 (1.7%) 13 (4.2%) 75 (1.9%)
Farmer 1 (<0.1%) 0 (0%) 1 (<0.1%) 0 (0%) 1 (<0.1%)
Trader 873 (22%) 37 (38%) 723 (20%) 187 (60%) 910 (23%)
Housewife 100 (2.6%) 4 (4.1%) 99 (2.7%) 5 (1.6%) 104 (2.6%)
Student 656 (17%) 16 (16%) 619 (17%) 53 (17%) 672 (17%)
Motorcycle taxi driver 1,128 (29%) 19 (19%) 1,136 (31%) 11 (3.5%) 1,147 (29%)
None 21 (0.5%) 0 (0%) 20 (0.5%) 1 (0.3%) 21 (0.5%)
Other 135 (3.5%) 1 (1.0%) 126 (3.4%) 10 (3.2%) 136 (3.4%)
Missing 2 1 3 0 3
P. Falciparum Exposure
Negative 3,897 (98%)
Positive 99 (2.5%)
P. Vivax Exposure
Negative 3,683 (92%)
Positive 313 (7.8%)
1 n (%)
2 Fisher's Exact Test for Count Data; Fisher's Exact Test for Count Data with simulated p-value (based on 2000 replicates)
table2 %>%
  as_flex_table() %>%
  flextable::save_as_docx(path = "./02_output/reports/table2.docx")

Table for Exposure Time

 table3 <- ffi_total %>%
   select(
     gender,
     age_cat,
     education_level,
     economic_activities,
     recent_exposure,
     historical_exposure
   ) %>%
   drop_na(recent_exposure, historical_exposure) %>%
   pivot_longer(
     cols = recent_exposure:historical_exposure,
     names_to = "exposure",
     values_to = "result_exposure"
   ) %>%
   mutate(
    exposure = case_when(
      exposure == "recent_exposure" ~ "Recent Exposure",
      exposure == "historical_exposure" ~ "Historical Exposure"
    )
   ) %>%
   tbl_strata(
    strata = exposure,
    .tbl_fun =
      ~ .x %>%
          tbl_summary(
            by = result_exposure,
            missing_text = "Missing"
          ) %>%
          add_p(
            test = list(all_categorical() ~ "fisher.test.simulate.p.values")
          ) %>%
          bold_p() %>%
          modify_header(label = "**Variable**") %>%
          bold_labels() 
   ) 

table3_overall <- ffi_total %>%
  select(
    gender,
    age_cat,
    education_level,
    economic_activities,
    recent_exposure,
    historical_exposure
  ) %>%
  drop_na(recent_exposure, historical_exposure) %>%
  tbl_summary(
    missing_text = "Missing"
  ) %>%
  modify_header(
    label = "**Variable**"
  ) %>%
  bold_labels() %>%
  modify_spanning_header(stat_0 ~ "**Overall**")

table3 <- tbl_merge(
  tbls = list(table3, table3_overall),
  tab_spanner = FALSE
)

table3
Variable Historical Exposure Recent Exposure Overall
Negative, N = 3,7281 Positive, N = 2681 p-value2 Negative, N = 3,7931 Positive, N = 2031 p-value2 N = 3,9961
Gender <0.001 <0.001
Male 1,886 (51%) 181 (68%) 1,910 (50%) 157 (77%) 2,067 (52%)
Female 1,842 (49%) 87 (32%) 1,883 (50%) 46 (23%) 1,929 (48%)
Age <0.001 <0.001
[0-10) 1,085 (29%) 5 (1.9%) 1,079 (29%) 11 (5.5%) 1,090 (27%)
[10-20) 899 (24%) 25 (9.3%) 918 (24%) 6 (3.0%) 924 (23%)
[20-30) 366 (9.8%) 14 (5.2%) 366 (9.7%) 14 (7.0%) 380 (9.5%)
[30-40) 392 (11%) 42 (16%) 406 (11%) 28 (14%) 434 (11%)
[40-50) 309 (8.3%) 54 (20%) 327 (8.6%) 36 (18%) 363 (9.1%)
[50-60) 303 (8.1%) 43 (16%) 305 (8.1%) 41 (20%) 346 (8.7%)
[60-70) 182 (4.9%) 38 (14%) 197 (5.2%) 23 (11%) 220 (5.5%)
[70+) 182 (4.9%) 47 (18%) 187 (4.9%) 42 (21%) 229 (5.7%)
Missing 10 0 8 2 10
Education Level <0.001 <0.001
No schooling 747 (20%) 17 (6.3%) 745 (20%) 19 (9.4%) 764 (19%)
Primary school 1,754 (47%) 171 (64%) 1,792 (47%) 133 (66%) 1,925 (48%)
Secondary school 1,126 (30%) 80 (30%) 1,156 (31%) 50 (25%) 1,206 (30%)
Higher education 98 (2.6%) 0 (0%) 97 (2.6%) 1 (0.5%) 98 (2.5%)
Missing 3 0 3 0 3
Economic Activities <0.001 <0.001
Day labourer 849 (23%) 18 (6.7%) 848 (22%) 19 (9.4%) 867 (22%)
Wood extractor 29 (0.8%) 4 (1.5%) 28 (0.7%) 5 (2.5%) 33 (0.8%)
Fisherman 21 (0.6%) 6 (2.2%) 22 (0.6%) 5 (2.5%) 27 (0.7%)
Livestock farmer 63 (1.7%) 12 (4.5%) 67 (1.8%) 8 (3.9%) 75 (1.9%)
Farmer 1 (<0.1%) 0 (0%) 1 (<0.1%) 0 (0%) 1 (<0.1%)
Trader 770 (21%) 140 (52%) 787 (21%) 123 (61%) 910 (23%)
Housewife 99 (2.7%) 5 (1.9%) 100 (2.6%) 4 (2.0%) 104 (2.6%)
Student 623 (17%) 49 (18%) 646 (17%) 26 (13%) 672 (17%)
Motorcycle taxi driver 1,124 (30%) 23 (8.6%) 1,139 (30%) 8 (3.9%) 1,147 (29%)
None 20 (0.5%) 1 (0.4%) 21 (0.6%) 0 (0%) 21 (0.5%)
Other 127 (3.4%) 9 (3.4%) 131 (3.5%) 5 (2.5%) 136 (3.4%)
Missing 2 1 3 0 3
recent_exposure
Negative 3,793 (95%)
Positive 203 (5.1%)
historical_exposure
Negative 3,728 (93%)
Positive 268 (6.7%)
1 n (%)
2 Fisher's Exact Test for Count Data; Fisher's Exact Test for Count Data with simulated p-value (based on 2000 replicates)
table3 %>%
  as_flex_table() %>%
  flextable::save_as_docx(path = "./02_output/reports/table3.docx")

Distance communities and regional Hospital

iquitos_centro <- tibble(
  "ffi_h_health_facility_name" = "Hospital Regional de Loreto",
  Longitude = -73.25385902080906,
  Latitude = -3.7264060164148716,
) %>%
  st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326) %>%
  st_transform(crs = 32718)

communities_sf <- ffi_household %>%
  select(
    ffi_h_district,
    ffi_h_code_community,
    ffi_h_community,
    ffi_gps_long,
    ffi_gps_lat
  ) %>%
  st_as_sf(
    coords = c("ffi_gps_long", "ffi_gps_lat"),
    crs = 4326
  ) %>%
  group_by(ffi_h_district, ffi_h_code_community, ffi_h_community) %>%
  summarise() %>%
  st_centroid()
## `summarise()` has grouped output by 'ffi_h_district', 'ffi_h_code_community'.
## You can override using the `.groups` argument.
## Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
## geometries of x
communities_distances <- communities_sf %>%
  st_transform(crs = 32718) %>%
  st_distance(iquitos_centro)

communities_distances <- enframe(communities_distances) %>%
  mutate(
    ffi_is_cod_com = communities_sf$ffi_h_code_community,
    ffi_is_community = communities_sf$ffi_h_community,
    distance = as.numeric(value)
  ) %>%
  select(-c(name, value))

Las Comunidades mas cercanas y mas lejanas por distrito:

communities_distances %>%
  mutate(
    ffi_h_district = communities_sf$ffi_h_district
  ) %>%
  group_by(ffi_h_district) %>%
  slice_min(distance, n = 1) %>%
  bind_rows(
    communities_distances %>%
      mutate(
        ffi_h_district = communities_sf$ffi_h_district
      ) %>%
      group_by(ffi_h_district) %>%
      slice_max(distance, n = 1)
  ) %>%
  arrange(ffi_h_district, distance)

Plots

Malaria Annual Parasite Index

data_malaria <- bind_rows(
  data_2000_2019,
  data_2020_2021
) %>%
  drop_na(District)

pob_loreto <- poblacion %>%
  filter(dep == "LORETO") %>%
  select(District = distr, Total)
malaria_cases_pob <- data_malaria %>%
  rowwise() %>%
  mutate(
    cases_malaria = sum(
      c_across(c(
        `Confirmed P. Falciparum`,
        `Confirmed P. Vivax`
      )),
      na.rm = TRUE
    )
  ) %>%
  group_by(District) %>%
  summarise(cases_malaria = sum(cases_malaria))

malaria_cases_pob <- malaria_cases_pob %>%
  left_join(
    pob_loreto
  ) %>%
  mutate(
    api = cases_malaria * 1000 / Total
  )
## Joining, by = "District"
data(Peru, package = "innovar")

malaria_cases_pob_sf <- Peru %>%
  filter(dep == "LORETO") %>%
  select(District = distr, geometry) %>% 
  right_join(
    malaria_cases_pob
  )
## Joining, by = "District"
figure1 <- ggplot(malaria_cases_pob_sf) +
  geom_sf(aes(fill = api, geometry = geometry)) +
  geom_sf(data = malaria_cases_pob_sf %>% dplyr::filter(District == "BELEN"), colour = "#aa6439", fill = NA, size = 1.5, aes(fill = api, geometry = geometry)) +
  geom_sf(data = malaria_cases_pob_sf %>% dplyr::filter(District == "INDIANA"), colour = "#256e5d", fill = NA, size = 1.5, aes(fill = api, geometry = geometry)) +
  scale_fill_distiller(
    name = "API",
    na.value = "black",
    # limits = c(0, 4000),
    palette = "RdYlGn",
    direction = -1,
    breaks = scales::pretty_breaks(n = 5),
    values = c(
      0,
      0.001,
      0.002,
      0.005,
      0.008,
      0.01,
      0.02,
      0.03,
      0.05,
      0.1,
      0.6,
      0.9,
      1
    )
  ) +
  labs(
    x = NULL,
    y = NULL,
    title = NULL
  ) +
  theme_classic() +
  geom_sf_label_repel(
    data = malaria_cases_pob_sf %>% dplyr::filter(District == "BELEN"),
    aes(label = District),
    min.segment.length = 0,
    force = 100,
    nudge_x = -1,
    seed = 10,
    colour = "#aa6439"
  ) +
  geom_sf_label_repel(
    data = malaria_cases_pob_sf %>% dplyr::filter(District == "INDIANA"),
    aes(label = District),
    min.segment.length = 0,
    force = 100,
    nudge_x = 1,
    seed = 10,
    colour = "#256e5d"
  )

figure1
## Warning in st_point_on_surface.sfc(data$geometry): st_point_on_surface may not
## give correct results for longitude/latitude data

## Warning in st_point_on_surface.sfc(data$geometry): st_point_on_surface may not
## give correct results for longitude/latitude data

ggsave(
  "./02_output/plots/figure1.png",
  figure1,
  device = grDevices::png,
  dpi = 300
)

Serological Results

By communities and type of plasmodium/time

# ffi_total %>%
#   ggplot(aes(
#     x = ffi_is_community,
#     fill = pv_historic
#   )) +
#   coord_flip(ylim = c(0, 0.25)) +
#   geom_bar(position = "fill")

plot1 <- ffi_total %>%
  drop_na(pf_recent:pv_historic) %>%
  left_join(
    communities_distances
  )  %>%
  pivot_longer(
    cols = pf_recent:pv_historic,
    names_to = "malaria",
    values_to = "result_malaria"
  ) %>%
  mutate(
    malaria = case_when(
      malaria == "pf_recent" ~ "Recent P. Falciparum",
      malaria == "pf_historic" ~ "Historical P. Falciparum",
      malaria == "pv_recent" ~ "Recent P. Vivax",
      malaria == "pv_historic" ~ "Historical P. Vivax"
    ),
    ffi_is_community = str_to_title(ffi_is_community),
    ffi_is_community = paste0(
      ffi_is_community,
      " (",
      str_to_title(ffi_is_district),
      ")"
    ),
    ffi_is_community = fct_reorder(
      ffi_is_community,
      distance,
      .desc = TRUE
    )
  ) %>%
  ggplot(aes(
    x = ffi_is_community,
    fill = result_malaria
  )) +
  facet_wrap(vars(malaria)) +
  geom_bar(position = "fill", color = "black") +
  coord_flip(ylim = c(0, 0.25)) +
  scale_y_continuous(
    labels = scales::percent_format()
  ) +
  #ggsci::scale_fill_lancet() +
  innovar::scale_fill_innova("npr") +
  labs(
    x = "Communities",
    y = "Percentage"
  ) +
  guides(
    fill = guide_legend("Results")
  ) +  
  theme_minimal() +
  theme(
    strip.text = element_text(
      face = "bold",
      size = 11
    ),
    axis.title = element_text(
      face = "bold",
      size = 11
    ),
    legend.title = element_text(
      face = "bold",
      size = 11
    )
  )
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot1

ggsave(
  "./02_output/plots/plot1_typeofmalaria_communities.png",
  plot1,
  dpi = 300,
  bg = "white",
  width = 10,
  height = 9
)

By communities, Indiana and type of plasmodium/time

plot1_indiana <- ffi_total %>%
  drop_na(pf_recent:pv_historic) %>%
  left_join(
    communities_distances
  )  %>%
  pivot_longer(
    cols = pf_recent:pv_historic,
    names_to = "malaria",
    values_to = "result_malaria"
  ) %>%
  mutate(
    malaria = case_when(
      malaria == "pf_recent" ~ "Recent P. Falciparum",
      malaria == "pf_historic" ~ "Historical P. Falciparum",
      malaria == "pv_recent" ~ "Recent P. Vivax",
      malaria == "pv_historic" ~ "Historical P. Vivax"
    ),
    ffi_is_community = str_to_title(ffi_is_community)
  ) %>%
  filter(ffi_is_district == "INDIANA") %>%
  mutate(
    ffi_is_community = fct_reorder(
      ffi_is_community,
      distance,
      .desc = TRUE
    )
  ) %>%
  ggplot(aes(
    x = ffi_is_community,
    fill = result_malaria
  )) +
  facet_wrap(vars(malaria)) +
  geom_bar(position = "fill", color = "black") +
  coord_flip(ylim = c(0, 0.25)) +
  scale_y_continuous(
    labels = scales::percent_format()
  ) +
  #ggsci::scale_fill_lancet() +
  innovar::scale_fill_innova("npr") +
  labs(
    title = str_wrap("Serological results by plasmodium type of malaria in the Indiana District", 100),
    x = "Communities",
    y = "Percentage"
  ) +
  guides(
    fill = guide_legend("Results")
  ) +  
  theme_minimal() +
  theme(
    strip.text = element_text(
      face = "bold",
      size = 11
    ),
    axis.title = element_text(
      face = "bold",
      size = 11
    ),
    legend.title = element_text(
      face = "bold",
      size = 11
    )
  )
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot1_indiana

ggsave(
  "./02_output/plots/plot1_typeofmalaria_communities_indiana.png",
  plot1_indiana,
  dpi = 300,
  bg = "white",
  width = 10,
  height = 9
)

By communities, Belen and type of plasmodium/time

plot1_belen <- ffi_total %>%
  drop_na(pf_recent:pv_historic) %>%
  left_join(
    communities_distances
  ) %>%
  pivot_longer(
    cols = pf_recent:pv_historic,
    names_to = "malaria",
    values_to = "result_malaria"
  ) %>%
  filter(ffi_is_district == "BELEN") %>%
  mutate(
    malaria = case_when(
      malaria == "pf_recent" ~ "Recent P. Falciparum",
      malaria == "pf_historic" ~ "Historical P. Falciparum",
      malaria == "pv_recent" ~ "Recent P. Vivax",
      malaria == "pv_historic" ~ "Historical P. Vivax"
    ),
    ffi_is_community = str_to_title(ffi_is_community),
    ffi_is_community = fct_reorder(
      ffi_is_community,
      distance,
      .desc = TRUE
    )
  ) %>%
  ggplot(aes(
    x = ffi_is_community,
    fill = result_malaria
  )) +
  facet_wrap(vars(malaria)) +
  geom_bar(position = "fill", color = "black") +
  coord_flip(ylim = c(0, 0.25)) +
  scale_y_continuous(
    labels = scales::percent_format()
  ) +
  #ggsci::scale_fill_lancet() +
  innovar::scale_fill_innova("npr") +
  labs(
    title = str_wrap("Serological results by plasmodium type of malaria in the Belen District", 100),
    x = "Communities",
    y = "Percentage"
  ) +
  guides(
    fill = guide_legend("Results")
  ) +  
  theme_minimal() +
  theme(
    strip.text = element_text(
      face = "bold",
      size = 11
    ),
    axis.title = element_text(
      face = "bold",
      size = 11
    ),
    legend.title = element_text(
      face = "bold",
      size = 11
    )
  )
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot1_belen

ggsave(
  "./02_output/plots/plot1_typeofmalaria_communities_belen.png",
  plot1_belen,
  dpi = 300,
  bg = "white",
  width = 10,
  height = 9
)

By communities, type of plasmodium exposure

plot2 <- ffi_total %>%
  drop_na(pf_exposure, pv_exposure) %>%
  left_join(
    communities_distances
  ) %>%
  pivot_longer(
    cols = pv_exposure:pf_exposure,
    names_to = "exposure",
    values_to = "result_exposure"
  )  %>%
  mutate(
    exposure = case_when(
         exposure == "pv_exposure" ~ "P. Vivax Exposure",
         exposure == "pf_exposure" ~ "P. Falciparum Exposure"
    ),
    ffi_is_community = str_to_title(ffi_is_community),
    ffi_is_community = fct_reorder(
      ffi_is_community,
      distance,
      .desc = TRUE
    )
  ) %>%
  ggplot(aes(
    x = ffi_is_community,
    fill = result_exposure
  )) +
  facet_wrap(vars(exposure)) +
  geom_bar(position = "fill", color = "black") +
  coord_flip(ylim = c(0, 0.40)) +
  scale_y_continuous(
    labels = scales::percent_format()
  ) +
  # ggsci::scale_fill_lancet() +
  innovar::scale_fill_innova("npr") +
  labs(
    x = "Communities",
    y = "Percentage"
  ) +
  guides(
    fill = guide_legend("Results")
  ) +
  theme_minimal() +
  theme(
    strip.text = element_text(
      face = "bold",
      size = 11
    ),
    axis.title = element_text(
      face = "bold",
      size = 11
    ),
    legend.title = element_text(
      face = "bold",
      size = 11
    )
  )
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot2

ggsave(
  "./02_output/plots/plot2_typeofmalaria_communities.png",
  plot2,
  dpi = 300,
  bg = "white",
  width = 10,
  height = 9
)

By communities, time of plasmodium exposure

plot3 <- ffi_total %>%
  drop_na(recent_exposure, historical_exposure) %>%
  left_join(
    communities_distances
  ) %>%
  pivot_longer(
    cols = recent_exposure:historical_exposure,
    names_to = "exposure",
    values_to = "result_exposure"
  ) %>%
  mutate(
    exposure = case_when(
      exposure == "recent_exposure" ~ "Recent Exposure",
      exposure == "historical_exposure" ~ "Historical Exposure"
    ),
    ffi_is_community = str_to_title(ffi_is_community),
    ffi_is_community = fct_reorder(
      ffi_is_community,
      distance,
      .desc = TRUE
    )
  ) %>%
  ggplot(aes(
    x = ffi_is_community,
    fill = result_exposure
  )) +
  facet_wrap(vars(exposure)) +
  geom_bar(position = "fill", color = "black") +
  coord_flip(ylim = c(0, 0.30)) +
  scale_y_continuous(
    labels = scales::percent_format()
  ) +
  # ggsci::scale_fill_lancet() +
  innovar::scale_fill_innova("npr") +
  labs(
    x = "Communities",
    y = "Percentage"
  ) +
  guides(
    fill = guide_legend("Results")
  ) +
  theme_minimal() +
  theme(
    strip.text = element_text(
      face = "bold",
      size = 11
    ),
    axis.title = element_text(
      face = "bold",
      size = 11
    ),
    legend.title = element_text(
      face = "bold",
      size = 11
    )
  )
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot3

ggsave(
  "./02_output/plots/plot3_typeofmalaria_communities.png",
  plot3,
  dpi = 300,
  bg = "white",
  width = 10,
  height = 9
)
# ffi_total %>%
#   drop_na(pf_recent:pv_historic, age_cat) %>%
#   pivot_longer(
#     cols = pf_recent:pv_historic,
#     names_to = "malaria",
#     values_to = "result_malaria"
#   ) %>%
#   mutate(
#     result_malaria = case_when(
#       result_malaria == "Positive" ~ 1,
#       TRUE ~ 0
#     ),
#     malaria = case_when(
#       malaria == "pf_recent" ~ "Recent P. Falciparum",
#       malaria == "pf_historic" ~ "Historical P. Falciparum",
#       malaria == "pv_recent" ~ "Recent P. Vivax",
#       malaria == "pv_historic" ~ "Historical P. Vivax"
#     ),
#     ffi_is_community = str_to_title(ffi_is_community)
#   ) %>%
#   group_by(ffi_is_community, age_cat, malaria) %>%
#   summarise(result_malaria = mean(result_malaria)) %>%
#   ggplot(
#     aes(
#       x = age_cat,
#       y = result_malaria,
#       color = malaria,
#       group = malaria
#     )
#   ) +
#   geom_point() +
#   geom_line() +
#   facet_wrap(vars(ffi_is_community)) +
#   theme_bw()

Seropositivity 4 malaria

By district

sero_4malaria_district <- ffi_total %>%
  drop_na(pf_recent:pv_historic, age_cat) %>%
  pivot_longer(
    cols = pf_recent:pv_historic,
    names_to = "malaria",
    values_to = "result_malaria"
  ) %>%
  mutate(
    result_malaria = case_when(
      result_malaria == "Positive" ~ 1,
      TRUE ~ 0
    ),
    malaria = case_when(
      malaria == "pf_recent" ~ "Recent P. Falciparum",
      malaria == "pf_historic" ~ "Historical P. Falciparum",
      malaria == "pv_recent" ~ "Recent P. Vivax",
      malaria == "pv_historic" ~ "Historical P. Vivax"
    ),
    across(
      c(ffi_is_community:ffi_is_health_facility_name),
      str_to_title
    )
  ) %>%
  group_by(ffi_is_district, age_cat, malaria) %>%
  summarise(result_malaria = mean(result_malaria)) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_malaria,
      color = malaria,
      group = malaria
    )
  ) +
  geom_point() +
  geom_line() +
  facet_wrap(vars(ffi_is_district)) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.40)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat'. You can
## override using the `.groups` argument.
sero_4malaria_district

ggsave(
  "./02_output/plots/plot4_sero_4malaria_district.png",
  sero_4malaria_district,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 7.5
)

By Health Facility

sero_4malaria_hf <- ffi_total %>%
  drop_na(pf_recent:pv_historic, age_cat) %>%
  pivot_longer(
    cols = pf_recent:pv_historic,
    names_to = "malaria",
    values_to = "result_malaria"
  ) %>%
  mutate(
    result_malaria = case_when(
      result_malaria == "Positive" ~ 1,
      TRUE ~ 0
    ),
    malaria = case_when(
      malaria == "pf_recent" ~ "Recent P. Falciparum",
      malaria == "pf_historic" ~ "Historical P. Falciparum",
      malaria == "pv_recent" ~ "Recent P. Vivax",
      malaria == "pv_historic" ~ "Historical P. Vivax"
    ),
    across(
      c(ffi_is_community:ffi_is_health_facility_name),
      str_to_title
    ),
    ffi_is_health_facility_name = paste(
      ffi_is_district,
      ffi_is_health_facility_name,
      sep = " - "
    )
  ) %>%
  group_by(ffi_is_health_facility_name, age_cat, malaria) %>%
  summarise(result_malaria = mean(result_malaria)) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_malaria,
      color = malaria,
      group = malaria
    )
  ) +
  geom_point() +
  geom_line() +
  facet_wrap(vars(ffi_is_health_facility_name)) +
  scale_y_continuous(
    labels = scales::percent_format()
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") + 
  theme_bw() +
  theme(
    axis.text.x = element_text(
      angle = 45,
      vjust = 1,
      hjust = 1
    )
  )
## `summarise()` has grouped output by 'ffi_is_health_facility_name', 'age_cat'.
## You can override using the `.groups` argument.
sero_4malaria_hf

ggsave(
  "./02_output/plots/plot5_sero_4malaria_hf.png",
  sero_4malaria_hf,
  dpi = 300,
  bg = "white",
  width = 10,
  height = 7
)

Seopositivity by Type of Malaria

By District

ffi_typeof_malaria <- ffi_total %>%
  drop_na(pf_exposure, pv_exposure, age_cat) %>%
  pivot_longer(
    cols = pv_exposure:pf_exposure,
    names_to = "exposure",
    values_to = "result_exposure"
  ) %>%
  mutate(
    exposure = case_when(
      exposure == "pv_exposure" ~ "P. Vivax Exposure",
      exposure == "pf_exposure" ~ "P. Falciparum Exposure"
    ),
    result_exposure = case_when(
      result_exposure == "Positive" ~ 1,
      TRUE ~ 0
    ),
    across(
      c(ffi_is_community:ffi_is_health_facility_name),
      str_to_title
    )
  )

sero_typeofmalaria_district <- ffi_typeof_malaria %>%
  group_by(ffi_is_district, age_cat, exposure) %>%
  summarise(result_exposure = mean(result_exposure)) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_wrap(vars(ffi_is_district)) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.40)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat'. You can
## override using the `.groups` argument.
ggsave(
  "./02_output/plots/plot6_sero_typeofmalaria_district.png",
  sero_typeofmalaria_district,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 7.5
)

By Health Facility

sero_typeofmalaria_hf <- ffi_typeof_malaria %>%
  group_by(ffi_is_health_facility_name, age_cat, exposure) %>%
  summarise(result_exposure = mean(result_exposure)) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_wrap(vars(ffi_is_health_facility_name)) +
  scale_y_continuous(
    labels = scales::percent_format()
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_health_facility_name', 'age_cat'.
## You can override using the `.groups` argument.
sero_typeofmalaria_hf

ggsave(
  "./02_output/plots/plot7_sero_typeofmalaria_hf.png",
  sero_typeofmalaria_hf,
  dpi = 300,
  bg = "white",
  width = 13,
  height = 9
)

Seropositivity by Time of Exposure

By District

ffi_timeofmalaria <- ffi_total %>%
  drop_na(recent_exposure, historical_exposure, age_cat) %>%
  pivot_longer(
    cols = recent_exposure:historical_exposure,
    names_to = "exposure",
    values_to = "result_exposure"
  ) %>%
  mutate(
    exposure = case_when(
      exposure == "recent_exposure" ~ "Recent Exposure",
      exposure == "historical_exposure" ~ "Historical Exposure"
    ),
    result_exposure = case_when(
      result_exposure == "Positive" ~ 1,
      TRUE ~ 0
    ),
    across(
      c(ffi_is_community:ffi_is_health_facility_name),
      str_to_title
    )
  )

sero_timeofmalaria_district <- ffi_timeofmalaria %>%
  group_by(ffi_is_district, age_cat, exposure) %>%
  summarise(result_exposure = mean(result_exposure)) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_wrap(vars(ffi_is_district)) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.40)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat'. You can
## override using the `.groups` argument.
ggsave(
  "./02_output/plots/plot8_sero_timeofmalaria_district.png",
  sero_timeofmalaria_district,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 7.5
)

By Health Facility

sero_timeofmalaria_hf <- ffi_timeofmalaria %>%
  group_by(ffi_is_health_facility_name, age_cat, exposure) %>%
  summarise(result_exposure = mean(result_exposure)) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_wrap(vars(ffi_is_health_facility_name)) +
  scale_y_continuous(
    labels = scales::percent_format()
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") + 
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_health_facility_name', 'age_cat'.
## You can override using the `.groups` argument.
sero_timeofmalaria_hf

ggsave(
  "./02_output/plots/plot9_sero_timeofmalaria_hf.png",
  sero_timeofmalaria_hf,
  dpi = 300,
  bg = "white",
  width = 13,
  height = 9
)

Relation with sex

library(rlang)
## 
## Attaching package: 'rlang'
## The following objects are masked from 'package:purrr':
## 
##     %@%, as_function, flatten, flatten_chr, flatten_dbl, flatten_int,
##     flatten_lgl, flatten_raw, invoke, splice
seropositivy_summarise <- function(data, type, variable, ...) {
  if (type == "4malaria") {
    ffi_total %>%
      drop_na(pf_recent:pv_historic, {{ variable }}, ...) %>%
      pivot_longer(
        cols = pf_recent:pv_historic,
        names_to = "malaria",
        values_to = "result_malaria"
      ) %>%
      mutate(
        result_malaria = case_when(
          result_malaria == "Positive" ~ 1,
          TRUE ~ 0
        ),
        malaria = case_when(
          malaria == "pf_recent" ~ "Recent P. Falciparum",
          malaria == "pf_historic" ~ "Historical P. Falciparum",
          malaria == "pv_recent" ~ "Recent P. Vivax",
          malaria == "pv_historic" ~ "Historical P. Vivax"
        ),
        across(
          c(ffi_is_community:ffi_is_health_facility_name),
          str_to_title
        )
      ) %>%
      group_by(ffi_is_district, {{ variable }}, ..., malaria) %>%
      summarise(result_malaria = mean(result_malaria))
  } else if (type == "typeofmalaria" ) {
    ffi_total %>%
      drop_na(pf_exposure, pv_exposure, {{ variable }}, ...) %>%
      pivot_longer(
        cols = pv_exposure:pf_exposure,
        names_to = "exposure",
        values_to = "result_exposure"
      ) %>%
      mutate(
        exposure = case_when(
          exposure == "pv_exposure" ~ "P. Vivax Exposure",
          exposure == "pf_exposure" ~ "P. Falciparum Exposure"
        ),
        result_exposure = case_when(
          result_exposure == "Positive" ~ 1,
          TRUE ~ 0
        ),
        across(
          c(ffi_is_community:ffi_is_health_facility_name),
          str_to_title
        )
      ) %>%
      group_by(ffi_is_district, {{ variable }}, ..., exposure) %>%
      summarise(result_exposure = mean(result_exposure))
  } else if (type == "timeofmalaria") {
    ffi_total %>%
      drop_na(recent_exposure, historical_exposure, 
              {{ variable }}, ...) %>%
      pivot_longer(
        cols = recent_exposure:historical_exposure,
        names_to = "exposure",
        values_to = "result_exposure"
      ) %>%
      mutate(
        exposure = case_when(
          exposure == "recent_exposure" ~ "Recent Exposure",
          exposure == "historical_exposure" ~ "Historical Exposure"
        ),
        result_exposure = case_when(
          result_exposure == "Positive" ~ 1,
          TRUE ~ 0
        ),
        across(
          c(ffi_is_community:ffi_is_health_facility_name),
          str_to_title
        )
      ) %>%
      group_by(ffi_is_district, {{ variable }}, ..., exposure) %>%
      summarise(result_exposure = mean(result_exposure))      
  }  
}

By 4 Malaria

sero_4malaria_district_gender <- seropositivy_summarise(
  ffi_total,
  "4malaria",
  age_cat,
  gender
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_malaria,
      color = malaria,
      group = malaria
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(gender),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.40)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_4malaria_district_gender

ggsave(
  "./02_output/plots/plot10_sero_4malaria_district_gender.png",
  sero_4malaria_district_gender,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Type of Malaria

sero_typeofmalaria_district_gender <- seropositivy_summarise(
  ffi_total,
  "typeofmalaria",
  age_cat,
  gender
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(gender),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.45)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_typeofmalaria_district_gender

ggsave(
  "./02_output/plots/plot11_sero_typeofmalaria_district_gender.png",
  sero_typeofmalaria_district_gender,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Time of Malaria

sero_timeofmalaria_district_gender <- seropositivy_summarise(
  ffi_total,
  "timeofmalaria",
  age_cat,
  gender
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(gender),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.45)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_timeofmalaria_district_gender

ggsave(
  "./02_output/plots/plot12_sero_timeofmalaria_district_gender.png",
  sero_timeofmalaria_district_gender,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

Relation with Education Level

By 4 Malaria

sero_4malaria_district_edulevel <- seropositivy_summarise(
  ffi_total,
  "4malaria",
  age_cat,
  education_level
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_malaria,
      color = malaria,
      group = malaria
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(education_level),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.40)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'education_level'. You can override using the `.groups` argument.
sero_4malaria_district_edulevel

ggsave(
  "./02_output/plots/plot13_sero_4malaria_district_edulevel.png",
  sero_4malaria_district_edulevel,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Type of Malaria

sero_typeofmalaria_district_edulevel <- seropositivy_summarise(
  ffi_total,
  "typeofmalaria",
  age_cat,
  education_level
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(education_level),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.45)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'education_level'. You can override using the `.groups` argument.
sero_typeofmalaria_district_edulevel

ggsave(
  "./02_output/plots/plot14_sero_typeofmalaria_district_edulevel.png",
  sero_typeofmalaria_district_edulevel,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Time of Malaria

sero_timeofmalaria_district_edulevel <- seropositivy_summarise(
  ffi_total,
  "timeofmalaria",
  age_cat,
  education_level
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(education_level),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.45)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'education_level'. You can override using the `.groups` argument.
sero_timeofmalaria_district_edulevel

ggsave(
  "./02_output/plots/plot15_sero_timeofmalaria_district_edulevel.png",
  sero_timeofmalaria_district_edulevel,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

Relation with Fever Month

By 4 malaria

ffi_fever_month <- ffi_total %>%
  drop_na(pf_recent:pv_historic, age_cat, ffi_is_fever_month) %>%
  pivot_longer(
    cols = pf_recent:pv_historic,
    names_to = "malaria",
    values_to = "result_malaria"
  ) %>%
  mutate(
    result_malaria = case_when(
      result_malaria == "Positive" ~ 1,
      TRUE ~ 0
    ),
    malaria = case_when(
      malaria == "pf_recent" ~ "Recent P. Falciparum",
      malaria == "pf_historic" ~ "Historical P. Falciparum",
      malaria == "pv_recent" ~ "Recent P. Vivax",
      malaria == "pv_historic" ~ "Historical P. Vivax"
    ),
    across(
      c(ffi_is_community:ffi_is_health_facility_name),
      str_to_title
    )
  ) %>%
  group_by(ffi_is_fever_month, age_cat, malaria) %>%
  summarise(result_malaria = mean(result_malaria))
## `summarise()` has grouped output by 'ffi_is_fever_month', 'age_cat'. You can
## override using the `.groups` argument.
sero_4malaria_fever_month <- ffi_fever_month %>%
  ggplot(
    aes(
      x = result_malaria,
      y = age_cat,
      group = age_cat
    )
  ) +
  geom_path(
    color = "#bdbdbd"
  ) +
  geom_point(
    aes(color = malaria),
    size = 3
  ) +
  facet_wrap(vars(ffi_is_fever_month)) +
  scale_x_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.5)
  ) +
  labs(
    y = "Age",
    x = "Seropositivity",
    title = str_wrap("Malaria seropositivity by type of exposure, plasmodium and presence of fever in the last month", 100)
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
ggsave(
  "./02_output/plots/plot16_sero_4malaria_fevermonth.png",
  sero_4malaria_fever_month,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Type of Malaria

ffi_fever_month_typeofmalaria <- ffi_total %>%
  drop_na(pf_recent:pv_historic, age_cat, ffi_is_fever_month) %>%
  pivot_longer(
    cols = pv_exposure:pf_exposure,
    names_to = "exposure",
    values_to = "result_exposure"
  ) %>%
    mutate(
      exposure = case_when(
        exposure == "pv_exposure" ~ "P. Vivax Exposure",
        exposure == "pf_exposure" ~ "P. Falciparum Exposure"
      ),
      result_exposure = case_when(
        result_exposure == "Positive" ~ 1,
        TRUE ~ 0
      ),
      across(
        c(ffi_is_community:ffi_is_health_facility_name),
        str_to_title
      )
    ) %>%
    group_by(ffi_is_fever_month, age_cat, exposure) %>%
    summarise(result_exposure = mean(result_exposure))
## `summarise()` has grouped output by 'ffi_is_fever_month', 'age_cat'. You can
## override using the `.groups` argument.
sero_typeofmalaria_fever_month <- ffi_fever_month_typeofmalaria %>%
  ggplot(
    aes(
      x = result_exposure,
      y = age_cat,
      group = age_cat
    )
  ) +
  geom_path(
    color = "#bdbdbd"
  ) +
  geom_point(
    aes(color = exposure),
    size = 3
  ) +
  facet_wrap(vars(ffi_is_fever_month)) +
  scale_x_continuous(
    labels = scales::percent_format(),
    # limits = c(0, 0.5)
  ) +
  labs(
    y = "Age",
    x = "Seropositivity",
    title = str_wrap("Malaria seropositivity by type of plasmodium and presence of fever in the last month", 100)
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
ggsave(
  "./02_output/plots/plot16_sero_typeofmalaria_fevermonth.png",
  sero_typeofmalaria_fever_month,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Time of Malaria

ffi_fever_month_timeofmalaria <- ffi_total %>%
  drop_na(pf_recent:pv_historic, age_cat, ffi_is_fever_month) %>%
  pivot_longer(
    cols = recent_exposure:historical_exposure,
    names_to = "exposure",
    values_to = "result_exposure"
  ) %>%
  mutate(
    exposure = case_when(
      exposure == "recent_exposure" ~ "Recent Exposure",
      exposure == "historical_exposure" ~ "Historical Exposure"
    ),
    result_exposure = case_when(
      result_exposure == "Positive" ~ 1,
      TRUE ~ 0
    ),
    across(
      c(ffi_is_community:ffi_is_health_facility_name),
      str_to_title
    )
  ) %>%
  group_by(ffi_is_fever_month, age_cat, exposure) %>%
  summarise(result_exposure = mean(result_exposure))
## `summarise()` has grouped output by 'ffi_is_fever_month', 'age_cat'. You can
## override using the `.groups` argument.
sero_timeofmalaria_fever_month <- ffi_fever_month_typeofmalaria %>%
  ggplot(
    aes(
      x = result_exposure,
      y = age_cat,
      group = age_cat
    )
  ) +
  geom_path(
    color = "#bdbdbd"
  ) +
  geom_point(
    aes(color = exposure),
    size = 3
  ) +
  facet_wrap(vars(ffi_is_fever_month)) +
  scale_x_continuous(
    labels = scales::percent_format(),
    # limits = c(0, 0.5)
  ) +
  labs(
    y = "Age",
    x = "Seropositivity",
    title = str_wrap("Malaria seropositivity by time of plasmodium and presence of fever in the last month", 100)
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
ggsave(
  "./02_output/plots/plot16_sero_timeofmalaria_fevermonth.png",
  sero_timeofmalaria_fever_month,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

Relation with Antimalarial Drugs

By 4 Malaria

sero_4malaria_district_antimaldrugs <- seropositivy_summarise(
  ffi_total,
  "4malaria",
  age_cat,
  ffi_is_antimal_drug_use
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_malaria,
      color = malaria,
      group = malaria
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_antimal_drug_use),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.50)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_antimal_drug_use'. You can override using the `.groups` argument.
sero_4malaria_district_antimaldrugs

ggsave(
  "./02_output/plots/plot19_sero_4malaria_district_antimaldrugs.png",
  sero_4malaria_district_antimaldrugs,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Type of Malaria

sero_typeofmalaria_district_antimaldrugs <- seropositivy_summarise(
  ffi_total,
  "typeofmalaria",
  age_cat,
  ffi_is_antimal_drug_use
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_antimal_drug_use),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.60)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_antimal_drug_use'. You can override using the `.groups` argument.
sero_typeofmalaria_district_antimaldrugs

ggsave(
  "./02_output/plots/plot20_sero_typeofmalaria_district_antimaldrugs.png",
  sero_typeofmalaria_district_antimaldrugs,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Time of Malaria

sero_timeofmalaria_district_antimaldrugs <- seropositivy_summarise(
  ffi_total,
  "timeofmalaria",
  age_cat,
  ffi_is_antimal_drug_use
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_antimal_drug_use),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.5)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_antimal_drug_use'. You can override using the `.groups` argument.
sero_timeofmalaria_district_antimaldrugs

ggsave(
  "./02_output/plots/plot21_sero_timeofmalaria_district_antimaldrugs.png",
  sero_timeofmalaria_district_antimaldrugs,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

Relation with time of someone had malaria

By general malaria

ffi_4malaria_mal_lifetime <- ffi_total %>% 
  drop_na(only_pv_exposure:freedom_malaria, 
          age_code, ffi_is_mal_lifetime) %>% 
  pivot_longer(
    cols = only_pv_exposure:freedom_malaria,
    names_to = "malaria",
    values_to = "result_malaria"
  ) %>% 
  mutate(
    result_malaria = case_when(
      result_malaria == "Positive" ~ 1,
      TRUE ~ 0
    ),
    malaria = case_when(
      malaria == "only_pv_exposure" ~ "Only P. vivax",
      malaria == "only_pf_exposure" ~ "Only P. falciparum",
      malaria == "pv_pf_exposure" ~ "P. vivax & falciparum Exposure",
      malaria == "freedom_malaria" ~ "Freedom from Malaria"
    ),
    across(
      c(ffi_is_community:ffi_is_health_facility_name),
      str_to_title
    )
  ) %>%
  group_by(ffi_is_mal_lifetime, age_code, malaria) %>%
  summarise(result_malaria = mean(result_malaria))
## `summarise()` has grouped output by 'ffi_is_mal_lifetime', 'age_code'. You can
## override using the `.groups` argument.
sero_4malaria_mal_lifetime <- ffi_4malaria_mal_lifetime %>%
  ggplot(
    aes(
      x = age_code,
      y = result_malaria,
      fill = malaria
    )
  ) +
  geom_area() +
  scale_x_continuous(
    limits = c(1, 8),
    breaks = seq(1, 8, 1),
    labels = c(
      "[0-10)",
      "[10-20)",
      "[20-30)",
      "[30-40)",
      "[40-50)",
      "[50-60)",
      "[60-70)",
      "[70+)"
    ),
    expand = c(0, 0)
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    expand = c(0, 0)
  ) +
  facet_wrap(vars(ffi_is_mal_lifetime)) +
  labs(
    y = "Seropositivity",
    x = "Age",
    title = str_wrap("Malaria seropositivity by type of exposure, plasmodium and how many times they think they have had malaria", 100)
  ) +
  guides(
    fill = guide_legend("Malaria")
  ) +
  innovar::scale_fill_innova("npr") +
  theme_bw() +
  theme(
    axis.text.x = element_text(
      angle = 45,
      vjust = 1,
      hjust = 1
    ),
    panel.spacing = unit(1, "lines")
  )

sero_4malaria_mal_lifetime

ggsave(
  "./02_output/plots/plot22_sero_4ofmalaria_mal_lifetime.png",
  sero_4malaria_mal_lifetime,
  dpi = 300,
  bg = "white",
  width = 11,
  height = 5
)

By Recent Malaria

ffi_recentmalaria_mal_lifetime <- ffi_total %>% 
  drop_na(only_pv_recent:freedom_malaria_recent, 
          age_code, ffi_is_mal_lifetime) %>% 
  pivot_longer(
    cols = only_pv_recent:freedom_malaria_recent,
    names_to = "malaria",
    values_to = "result_malaria"
  ) %>% 
  mutate(
    result_malaria = case_when(
      result_malaria == "Positive" ~ 1,
      TRUE ~ 0
    ),
    malaria = case_when(
      malaria == "only_pv_recent" ~ "Only P. vivax Recent",
      malaria == "only_pf_recent" ~ "Only P. falciparum Recent",
      malaria == "pv_pf_recent" ~ "P. vivax & falciparum Recent",
      malaria == "freedom_malaria_recent" ~ "Freedom from Malaria Recent"
    ),
    across(
      c(ffi_is_community:ffi_is_health_facility_name),
      str_to_title
    )
  ) %>%
  group_by(ffi_is_mal_lifetime, age_code, malaria) %>%
  summarise(result_malaria = mean(result_malaria))
## `summarise()` has grouped output by 'ffi_is_mal_lifetime', 'age_code'. You can
## override using the `.groups` argument.
sero_recentmalaria_mal_lifetime <- ffi_recentmalaria_mal_lifetime %>%
  ggplot(
    aes(
      x = age_code,
      y = result_malaria,
      fill = malaria
    )
  ) +
  geom_area() +
  scale_x_continuous(
    limits = c(1, 8),
    breaks = seq(1, 8, 1),
    labels = c(
      "[0-10)",
      "[10-20)",
      "[20-30)",
      "[30-40)",
      "[40-50)",
      "[50-60)",
      "[60-70)",
      "[70+)"
    ),
    expand = c(0, 0)
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    expand = c(0, 0)
  ) +
  facet_wrap(vars(ffi_is_mal_lifetime)) +
  labs(
    y = "Seropositivity",
    x = "Age",
    title = str_wrap("Malaria seropositivity by recent exposure and how many times they think they have had malaria", 100)
  ) +
  guides(
    fill = guide_legend("Malaria")
  ) +
  innovar::scale_fill_innova("npr") +
  theme_bw() +
  theme(
    axis.text.x = element_text(
      angle = 45,
      vjust = 1,
      hjust = 1
    ),
    panel.spacing = unit(1, "lines")
  )

sero_recentmalaria_mal_lifetime

ggsave(
  "./02_output/plots/plot23_sero_recent_malaria_mal_lifetime.png",
  sero_recentmalaria_mal_lifetime,
  dpi = 300,
  bg = "white",
  width = 11,
  height = 5
)

By Historic Malaria

ffi_historicmalaria_mal_lifetime <- ffi_total %>% 
  drop_na(only_pv_historic:freedom_malaria_historic, 
          age_code, ffi_is_mal_lifetime) %>% 
  pivot_longer(
    cols = only_pv_historic:freedom_malaria_historic,
    names_to = "malaria",
    values_to = "result_malaria"
  ) %>% 
  mutate(
    result_malaria = case_when(
      result_malaria == "Positive" ~ 1,
      TRUE ~ 0
    ),
    malaria = case_when(
      malaria == "only_pv_historic" ~ "Only P. vivax Historic",
      malaria == "only_pf_historic" ~ "Only P. falciparum Historic",
      malaria == "pv_pf_historic" ~ "P. vivax & falciparum Historic",
      malaria == "freedom_malaria_historic" ~ "Freedom from Malaria Historic"
    ),
    across(
      c(ffi_is_community:ffi_is_health_facility_name),
      str_to_title
    )
  ) %>%
  group_by(ffi_is_mal_lifetime, age_code, malaria) %>%
  summarise(result_malaria = mean(result_malaria))
## `summarise()` has grouped output by 'ffi_is_mal_lifetime', 'age_code'. You can
## override using the `.groups` argument.
sero_historicmalaria_mal_lifetime <- ffi_historicmalaria_mal_lifetime %>%
  ggplot(
    aes(
      x = age_code,
      y = result_malaria,
      fill = malaria
    )
  ) +
  geom_area() +
  scale_x_continuous(
    limits = c(1, 8),
    breaks = seq(1, 8, 1),
    labels = c(
      "[0-10)",
      "[10-20)",
      "[20-30)",
      "[30-40)",
      "[40-50)",
      "[50-60)",
      "[60-70)",
      "[70+)"
    ),
    expand = c(0, 0)
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    expand = c(0, 0)
  ) +
  facet_wrap(vars(ffi_is_mal_lifetime)) +
  labs(
    y = "Seropositivity",
    x = "Age",
    title = str_wrap("Malaria seropositivity by historic exposure and how many times they think they have had malaria", 100)
  ) +
  guides(
    fill = guide_legend("Malaria")
  ) +
  innovar::scale_fill_innova("npr") +
  theme_bw() +
  theme(
    axis.text.x = element_text(
      angle = 45,
      vjust = 1,
      hjust = 1
    ),
    panel.spacing = unit(1, "lines")
  )

sero_historicmalaria_mal_lifetime

ggsave(
  "./02_output/plots/plot24_sero_historic_malaria_mal_lifetime.png",
  sero_historicmalaria_mal_lifetime,
  dpi = 300,
  bg = "white",
  width = 11,
  height = 5
)

Relation where someone usually bathe

By 4 Malaria

sero_4malaria_district_ussualybathe<- seropositivy_summarise(
  ffi_total,
  "4malaria",
  age_cat,
  ffi_is_place_shower
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_malaria,
      color = malaria,
      group = malaria
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_place_shower),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.50)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_place_shower'. You can override using the `.groups` argument.
sero_4malaria_district_ussualybathe

ggsave(
  "./02_output/plots/plot25_sero_4malaria_district_ussualybathe.png",
  sero_4malaria_district_ussualybathe,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Type of Malaria

sero_typeofmalaria_district_ussualybathe <- seropositivy_summarise(
  ffi_total,
  "typeofmalaria",
  age_cat,
  ffi_is_place_shower
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_place_shower),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.60)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_place_shower'. You can override using the `.groups` argument.
sero_typeofmalaria_district_ussualybathe

ggsave(
  "./02_output/plots/plot26_sero_typeofmalaria_district_ussualybathe.png",
  sero_typeofmalaria_district_ussualybathe,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Time of Malaria

sero_timeofmalaria_district_ussualybathe <- seropositivy_summarise(
  ffi_total,
  "timeofmalaria",
  age_cat,
  ffi_is_place_shower
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_place_shower),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.5)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_place_shower'. You can override using the `.groups` argument.
sero_timeofmalaria_district_ussualybathe

ggsave(
  "./02_output/plots/plot27_sero_timeofmalaria_district_ussualybathe.png",
  sero_timeofmalaria_district_ussualybathe,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

Relation with those who have a mosquito net

By 4 Malaria

sero_4malaria_district_mosquitnet <- seropositivy_summarise(
  ffi_total,
  "4malaria",
  age_cat,
  ffi_is_mosq_net
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_malaria,
      color = malaria,
      group = malaria
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_mosq_net),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.50)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_mosq_net'. You can override using the `.groups` argument.
sero_4malaria_district_mosquitnet

ggsave(
  "./02_output/plots/plot28_sero_4malaria_district_mosquitnet.png",
  sero_4malaria_district_mosquitnet,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Type of Malaria

sero_typeofmalaria_district_mosquitnet <- seropositivy_summarise(
  ffi_total,
  "typeofmalaria",
  age_cat,
  ffi_is_mosq_net
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_mosq_net),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.60)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_mosq_net'. You can override using the `.groups` argument.
sero_typeofmalaria_district_mosquitnet

ggsave(
  "./02_output/plots/plot29_sero_typeofmalaria_district_mosquitnet.png",
  sero_typeofmalaria_district_mosquitnet,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Time of Malaria

sero_timeofmalaria_district_mosquitnet <- seropositivy_summarise(
  ffi_total,
  "timeofmalaria",
  age_cat,
  ffi_is_mosq_net
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_mosq_net),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.5)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_mosq_net'. You can override using the `.groups` argument.
sero_timeofmalaria_district_mosquitnet

ggsave(
  "./02_output/plots/plot30_sero_timeofmalaria_district_mosquitnet.png",
  sero_timeofmalaria_district_mosquitnet,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

Relation with those who have a trip in the last month

By 4 Malaria

sero_4malaria_district_tripmonth <- seropositivy_summarise(
  ffi_total,
  "4malaria",
  age_cat,
  ffi_is_trip_month
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_malaria,
      color = malaria,
      group = malaria
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_trip_month),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.50)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_trip_month'. You can override using the `.groups` argument.
sero_4malaria_district_tripmonth

ggsave(
  "./02_output/plots/plot31_sero_4malaria_district_tripmonth.png",
  sero_4malaria_district_tripmonth,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Type of Malaria

sero_typeofmalaria_district_tripmonth <- seropositivy_summarise(
  ffi_total,
  "typeofmalaria",
  age_cat,
  ffi_is_trip_month
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_trip_month),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.60)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_trip_month'. You can override using the `.groups` argument.
sero_typeofmalaria_district_tripmonth

ggsave(
  "./02_output/plots/plot32_sero_typeofmalaria_district_tripmonth.png",
  sero_typeofmalaria_district_tripmonth,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Time of Malaria

sero_timeofmalaria_district_tripmonth <- seropositivy_summarise(
  ffi_total,
  "timeofmalaria",
  age_cat,
  ffi_is_trip_month
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(ffi_is_trip_month),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    #limits = c(0, 0.5)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_trip_month'. You can override using the `.groups` argument.
sero_timeofmalaria_district_tripmonth

ggsave(
  "./02_output/plots/plot33_sero_timeofmalaria_district_tripmonth.png",
  sero_timeofmalaria_district_tripmonth,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

Descriptive 01_data

plot_4_2 <- ffi_total %>%
  filter(ffi_is_malaria %in% c("No", "Yes")) %>%
  drop_na(age_cat, pv_historic) %>%
  mutate(
    malaria_gender = paste(gender, ffi_is_malaria)
  ) %>%
  count(pv_historic, age_cat, malaria_gender) %>%
  mutate(Percentage = n / sum(n)) %>%
  mutate(
    Percentage = case_when(
      str_detect(malaria_gender, "Female") ~ Percentage * -1,
      TRUE ~ Percentage
    )
  ) %>%
  ggplot(aes(
    y = age_cat,
    x = Percentage,
    fill = malaria_gender
  )) +
  geom_col(
    position = position_stack(reverse = TRUE),
    color = "black"
  ) +
  labs(
    x = "Age Group",
    y = NULL,
    title = "Population structure by age groups, gender and malaria transmission"
  ) +
  facet_wrap(vars(pv_historic)) + 
  scale_x_continuous(
    limits = c(-0.25, 0.25),
    breaks = seq(-0.25, 0.25, 0.05),
    labels = c(paste0(seq(25, 0, -5), "%"), paste0(seq(5, 25, 5), "%"))
  ) +
  # innovar::scale_fill_innova("npr") +
  scale_fill_discrete(
    type = innovar::innova_pal("npr")(4),
    limits = c("Male Yes", "Male No", "Female No", "Female Yes")
  ) +
  guides(
    fill = guide_legend("Have you ever \nhad malaria?")
  ) +
  geom_vline(xintercept = 0, size = 1) +
  theme_bw(base_size = 12) +
  theme(
    plot.title = element_text(
      size = 14,
      hjust = 0.5,
      face = "bold"
    ),
    strip.text = element_text(
      size = 12,
      face = "bold"
    ),
    legend.title = element_text(
      size = 12,
      face = "bold"
    ),
    plot.margin = margin(5, 15, 5, 15)
  )

Descriptive 01_data

plot_4_2 <- ffi_total %>%
  filter(ffi_is_malaria %in% c("No", "Yes")) %>%
  drop_na(age_cat, pv_historic) %>%
  mutate(
    malaria_gender = paste(gender, ffi_is_malaria)
  ) %>%
  count(pv_historic, age_cat, malaria_gender) %>%
  mutate(Percentage = n / sum(n)) %>%
  mutate(
    Percentage = case_when(
      str_detect(malaria_gender, "Female") ~ Percentage * -1,
      TRUE ~ Percentage
    )
  ) %>%
  ggplot(aes(
    y = age_cat,
    x = Percentage,
    fill = malaria_gender
  )) +
  geom_col(
    position = position_stack(reverse = TRUE),
    color = "black"
  ) +
  labs(
    x = "Age Group",
    y = NULL,
    title = "Population structure by age groups, gender and malaria transmission"
  ) +
  facet_wrap(vars(pv_historic)) + 
  scale_x_continuous(
    limits = c(-0.25, 0.25),
    breaks = seq(-0.25, 0.25, 0.05),
    labels = c(paste0(seq(25, 0, -5), "%"), paste0(seq(5, 25, 5), "%"))
  ) +
  # innovar::scale_fill_innova("npr") +
  scale_fill_discrete(
    type = innovar::innova_pal("npr")(4),
    limits = c("Male Yes", "Male No", "Female No", "Female Yes")
  ) +
  guides(
    fill = guide_legend("Have you ever \nhad malaria?")
  ) +
  geom_vline(xintercept = 0, size = 1) +
  theme_bw(base_size = 12) +
  theme(
    plot.title = element_text(
      size = 14,
      hjust = 0.5,
      face = "bold"
    ),
    strip.text = element_text(
      size = 12,
      face = "bold"
    ),
    legend.title = element_text(
      size = 12,
      face = "bold"
    ),
    plot.margin = margin(5, 15, 5, 15)
  )

Sankey_seropositive

library(ggsankey)

ffi_format_sankey <- ffi_total %>%
  mutate(
    ffi_is_access_malaria_yn_hf = factor(
      ffi_is_access_malaria_yn_hf,
      label = c("No", "Yes")
    ),
    ffi_is_mal_lifetime = as.character(ffi_is_mal_lifetime),
    ffi_is_mal_lifetime = replace_na(ffi_is_mal_lifetime, "0 times"),
    ffi_is_mal_lifetime = factor(
      ffi_is_mal_lifetime,
      labels = c(
        "0 times",
        "1 to 3 times",
        "3 to 7 times",
        "More than 7 times"
      )
    )
  )

sankey_seropositive_answ1 <- ffi_format_sankey %>%
  pivot_longer(
    cols = c(recent_exposure, ffi_is_mal_lifetime, ffi_is_access_malaria_yn_hf),
    names_to = "malaria_behavior1",
    values_to = "malaria_answ1"
  ) %>%
  count(malaria_behavior1, malaria_answ1) %>%
  group_by(malaria_behavior1) %>%
  mutate(
    percentage = scales::percent(
      n / sum(n),
      accuracy = 0.1
    )
  ) %>%
  ungroup() %>%
  mutate(
    malaria_behavior1 = fct_relevel(
      malaria_behavior1,
      "ffi_is_mal_lifetime",
      "ffi_is_access_malaria_yn_hf",
      "recent_exposure"
    ),
    malaria_percent1 = paste0(
      malaria_answ1,
      paste0("\n(", percentage, ")")
    ),
    malaria_percent1 = as_factor(malaria_percent1)
  ) %>%
  select(malaria_behavior1, malaria_answ1, malaria_percent1)


sankey_seropositive <- ffi_format_sankey %>%
  drop_na(ffi_is_mal_lifetime, 
  ffi_is_access_malaria_yn_hf,
  recent_exposure
  ) %>%
  make_long(
    ffi_is_mal_lifetime,
    ffi_is_access_malaria_yn_hf, 
    recent_exposure
  ) %>%
  left_join(
    sankey_seropositive_answ1,
      by = c(
        "x" = "malaria_behavior1",
        "node" = "malaria_answ1"
      )
  ) %>%
  mutate(
    node = malaria_percent1,
    node = fct_rev(node)
  ) %>%
  select(-malaria_percent1) %>%
  left_join(
    sankey_seropositive_answ1,
    by = c(
      "next_x" = "malaria_behavior1",
      "next_node" = "malaria_answ1"
    )
  ) %>%
  mutate(next_node = malaria_percent1) %>%
  select(-malaria_percent1) %>%
  ggplot(aes(
    x = x,
    next_x = next_x,
    node = node,
    next_node = next_node,
    fill = factor(node),
    label = node
  )) +
  geom_sankey(
    flow.alpha = .8,
    node.color = "gray30"
  ) +
  geom_sankey_label(size = 4, color = "white", fill = "gray30") +
  scale_x_discrete(
    labels = str_wrap(
      c(
        "How many times do you think you have had malaria in your life?",
        "If you had malaria, would you go to the health facility?",
        "Recent exposure to any type of plasmodium"
      ),
      30
    )
  ) +
  theme_sankey(base_size = 18) +
  innovar::scale_fill_innova("npr") +
  labs(
    x = NULL,
    title = "Behaviour associated with recent malaria exposure"
  ) +
  theme(
    legend.position = "none",
    plot.title = element_text(hjust = .5),
    plot.margin = margin(5, 5, 5, 5)
  )
## Warning: attributes are not identical across measure variables;
## they will be dropped
ggsave("./02_output/plots/plot34_sankey_seropositive.png",
       sankey_seropositive,
       height = 7,
       width = 14,
       dpi = 300)

Relation gender and ocupation

By 4 Malaria

sero_4malaria_district_gender_economic <- seropositivy_summarise(
  ffi_total,
  "4malaria",
  economic_activities,
  gender
) %>%
  ggplot(
    aes(
      x = economic_activities,
      y = result_malaria,
      color = malaria,
      group = malaria
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(gender),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.40)
  ) +
  labs(
    x = "Economic Activities",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw() +
  theme(
    axis.text.x = element_text(
      angle = 45,
      vjust = 1,
      hjust = 1
    )
  )
## `summarise()` has grouped output by 'ffi_is_district', 'economic_activities',
## 'gender'. You can override using the `.groups` argument.
sero_4malaria_district_gender_economic

ggsave(
  "./02_output/plots/plot35_sero_4malaria_district_gender_economic.png",
  sero_4malaria_district_gender_economic,
  dpi = 300,
  bg = "white",
  width = 11,
  height = 7.5,
  scale = 0.9
)

By Type of Malaria

sero_typeofmalaria_district_gender <- seropositivy_summarise(
  ffi_total,
  "typeofmalaria",
  age_cat,
  gender
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(gender),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.45)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_typeofmalaria_district_gender

ggsave(
  "./02_output/plots/plot11_sero_typeofmalaria_district_gender.png",
  sero_typeofmalaria_district_gender,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

By Time of Malaria

sero_timeofmalaria_district_gender <- seropositivy_summarise(
  ffi_total,
  "timeofmalaria",
  age_cat,
  gender
) %>%
  ggplot(
    aes(
      x = age_cat,
      y = result_exposure,
      color = exposure,
      group = exposure
    )
  ) +
  geom_point() +
  geom_line() +
  facet_grid(
    vars(gender),
    vars(ffi_is_district)    
  ) +
  scale_y_continuous(
    labels = scales::percent_format(),
    limits = c(0, 0.45)
  ) +
  labs(
    x = "Age",
    y = "Seropositivity"
  ) +
  guides(
    color = guide_legend("Malaria")
  ) +
  innovar::scale_color_innova("npr") +
  theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_timeofmalaria_district_gender

ggsave(
  "./02_output/plots/plot12_sero_timeofmalaria_district_gender.png",
  sero_timeofmalaria_district_gender,
  dpi = 300,
  bg = "white",
  width = 12,
  height = 8.5
)

Maps

library(sf)
library(leaflet)
ffi_total_gps <- ffi_total %>%
  select(
    ffi_is_cod_com:ffi_is_cod_ind,
    pf_recent:pv_historic,
    pv_exposure:historical_exposure
  ) %>%
  left_join(
    ffi_household %>%
      select(
        ffi_h_code_community:ffi_h_code_household,
        ffi_h_community
      ),
    by = c(
      "ffi_is_cod_com" = "ffi_h_code_community",
      "ffi_is_cod_household" = "ffi_h_code_household"
    )
  ) 

ffi_household_gps <- ffi_total_gps %>%
  select(
    ffi_is_cod_com:ffi_is_cod_household,
    ffi_h_community,
    recent_exposure
  ) %>%
  mutate(
    recent_exposure = case_when(
      recent_exposure == "Positive" ~ 1,
      TRUE ~ 0
    )
  ) %>%
  group_by(
    across(c(ffi_is_cod_com:ffi_h_community))
  ) %>%
  summarise(
    recent_exposure = mean(recent_exposure)
  ) %>%
  ungroup()
## `summarise()` has grouped output by 'ffi_is_cod_com', 'ffi_is_cod_household'.
## You can override using the `.groups` argument.
  # mutate(
  #   color_marker = case_when(
  #     recent_exposure == 0 ~ "red",
  #     TRUE ~ "black"
  #   )
  # )

ffi_household_gps <- ffi_household_gps %>%
  left_join(
    ffi_household %>%
      select(
        ffi_h_code_community:ffi_h_code_household,
        ffi_h_district,
        ffi_gps_long,
        ffi_gps_lat
      ),
    by = c(
      "ffi_is_cod_com" = "ffi_h_code_community",
      "ffi_is_cod_household" = "ffi_h_code_household"
    )
  ) %>%
  mutate(
    ffi_h_household_id = paste0(ffi_is_cod_com, ffi_is_cod_household),
    ffi_is_cod_com_label = paste0(
      "Cod: ",
      ffi_is_cod_household,
      " - ",
      str_to_title(ffi_h_community),
      " (",
      str_to_title(ffi_h_district),
      ")"
    )
  ) %>%
  st_as_sf(
    coords = c("ffi_gps_long", "ffi_gps_lat"),
    crs = 4326
  ) 
  

  
# colors_pal <- rev(innovar:::innova_palettes[["ecomst"]])
# pal <- colorNumeric(
#   colorRamp(colors_pal),
#   ffi_household_gps$recent_exposure
# )

pal <- colorNumeric(
  hcl.colors(17, palette = "zissou"),
  ffi_household_gps$recent_exposure
)

# icons_household <- awesomeIcons(
#   icon = "ios-home",
#   iconColor = "black",
#   library = "ion",
#   markerColor = innovar::innova_pal("ecomst", reverse = TRUE)(17)
# )

communities_sf <- communities_sf %>%
  mutate(
    ffi_h_community = str_to_title(ffi_h_community)
  ) %>%
  left_join(
    ffi_household %>%
      select(ffi_h_district, ffi_h_code_community) %>%
      distinct()
  )  %>%
  mutate(
    ffi_h_community_label = paste0(
      ffi_h_community,
      " (",
      str_to_title(ffi_h_district),
      ")"
    )
  )
## Joining, by = c("ffi_h_district", "ffi_h_code_community")
household_communities_leaft <- ffi_household_gps %>%
  leaflet() %>%
  addProviderTiles(
    providers$OpenStreetMap,
    group = "OpenStreetMap"
  ) %>%
  addCircleMarkers(
    layerId = ~ffi_h_household_id,
    label = ~ffi_is_cod_com_label,
    color = ~ pal(recent_exposure),
    group = "Households",
    radius = 7,
    weight = 5,
    opacity = 1,
    fillOpacity = 0.1,
    labelOptions = labelOptions(
      style = list(
        "font-weight" = "bold",
        padding = "3px 8px"
      ),
      textsize = "12px",
      direction = "auto"
    )
  ) %>%
  # addLegend(
  #   title = "Recent Exposure",
  #   pal = pal, 
  #   values = ~ recent_exposure, 
  #   group = "circles", 
  #   position = "bottomleft",
  #   transform = ~ scales::percent_format(),
  #   opacity = 1
  # ) %>%<font-awesome-icon icon="fa-solid fa-location-dot" />
  leaflegend::addLegendNumeric(
    title = "Recent Exposure",
    pal = pal,
    values = ~ recent_exposure,
    position = "bottomright",
    orientation = "horizontal",
    height = 20,
    width = 100,
    decreasing = FALSE,
    numberFormat = scales::percent_format(),
    group = "circles"
  )  %>%
  addAwesomeMarkers(
    data = communities_sf,
    layerId = ~ffi_h_code_community,
    label = ~ffi_h_community_label,
    group = "Communities"
  ) %>%
  addProviderTiles(
    providers$OpenStreetMap,
    group = "OpenStreetMap"
  ) %>%
  addTiles(
    urlTemplate = "http://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}&s=Ga",
    attribution = "Google Maps",
    options = leaflet::tileOptions(
      maxNativeZoom = 19,
      maxZoom = 20
    ),
    group = "Google Maps"
  ) %>%
  addTiles(
    urlTemplate = "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
    attribution = "Satellite View",
    options = leaflet::tileOptions(
      maxNativeZoom = 19,
      maxZoom = 20
    ),
    group = "Satellite View"
  ) %>%
  # Layers control*
  addLayersControl(
    overlayGroups = c("Households", "Communities"),
    baseGroups = c("OpenStreetMap", "Google Maps", "Satellite View"),
    options = layersControlOptions(collapsed = FALSE)
  ) %>%
  # addLegend(
  #   "topright",
  #   pal = innovar::innova_pal("ecomst", reverse = TRUE)(980)
  # )  %>%
  # addLegend(
  #   position = "bottomright",
  #   colors = c(
  #     "white; width:15px; height:15px;
  #                border:5px solid red; border-radius:50%;",
  #     "white; width:7.5px; height:7.5px; margin-top: 5px;
  #                border:5px solid black; border-radius:50%; margin-left:2px;"
  #   ),
  #   labels = c(
  #     "<div style='display: inline-block; height: 10px;
  #                margin-top: 8px;line-height: 10px;font-weight: bold;
  #                color: black; '>At least 1 person with recent malaria</div>",
  #     "<div style='display: inline-block;height: 10px;
  #                margin-top: 8px;line-height: 10px;font-weight: bold;
  #                color: black; margin-top: 10px;
  #                margin-left:5px'>No one with recent malaria at household</div>"
  #   ),
  #   opacity = 1
  # ) %>%
  leaflet.extras::addResetMapButton()
htmlwidgets::saveWidget(
  household_communities_leaft,
  file = "./02_output/plots/household_communities_leaft.html"
)

webshot::webshot(
  "./02_output/plots/household_communities_leaft.html",
  "./02_output/plots/household_communities_leaft.png",
  cliprect = "viewport",
  zoom = 4
)
LS0tCnRpdGxlOiAiRGVzY3JpcHRpdmUgYW5hbHlzaXMiCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBybWRmb3JtYXRzOjpkb3duY3V0ZToKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICBoaWdobGlnaHQ6IGthdGUKICAgIHRvY19kZXB0aDogMwogICAgZGVmYXVsdF9zdHlsZTogZGFyawogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBoaWdobGlnaHRfZG93bmxpdDogdHJ1ZQplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KIyMgR2xvYmFsIG9wdGlvbnMKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGNhY2hlID0gVFJVRSwKICB3YXJuaW5ncyA9IEZBTFNFLAogIG1lc3NhZ2VzID0gRkFMU0UKKQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc2YpCmxpYnJhcnkoZ2dzZmxhYmVsKQpgYGAKCiMgSW1wb3J0IGRhdGEKCmBgYHtyfQpzZXJvbG9neSA8LSByZWFkX2NzdigiLi8wMV9kYXRhL3Jhdy9GRkkucGVydS5zZXJvbG9neS5rbWVhbnMyLmNzdiIpICU+JQogIHJlbmFtZShmZmlfaXNfY29kZSA9IENvZGlnbykgJT4lCiAgc2VsZWN0KC0xKQoKZmZpX2luZGl2aWR1YWwgPC0gcmVhZF9jc3YoIi4vMDFfZGF0YS9yYXcvaW5kaXZpZHVhbHNfcmVzdWx0X3NoYXJlXzA3MjAyMi5jc3YiKQpmZmlfaG91c2Vob2xkIDwtIHJlYWRfY3N2KCIuLzAxX2RhdGEvcmF3L2hvdXNlaG9sZF9ncHNfc2hhcmVfMDcyMDIyLmNzdiIpCmRhdGFfMjAwMF8yMDE5IDwtIHJlYWRfY3N2KCIuLzAxX2RhdGEvcmF3L0RhdGFfRkZJXzIwMDBfMjAxOV8yMDIxMjQwNS5jc3YiKQpkYXRhXzIwMjBfMjAyMSA8LSByZWFkX2NzdigiLi8wMV9kYXRhL3Jhdy9EYXRhX0ZGSV8yMDIwXzIwMjFfMjAyMTA2MjkuY3N2IikKcG9ibGFjaW9uIDwtIHJlYWRSRFMoIi4vMDFfZGF0YS9yYXcvcG9ibGFjaW9uX2luZWlfMjAxNy5yZHMiKQpgYGAKCiMgRm9ybWF0IGRhdGEKCmBgYHtyfQpmZmlfdG90YWwgPC0gZmZpX2luZGl2aWR1YWwgJT4lCiAgZnVsbF9qb2luKAogICAgc2Vyb2xvZ3kgJT4lCiAgICAgIG11dGF0ZSgKICAgICAgICBmZmlfaXNfY29kZSA9IHBhc3RlMCgwLCBmZmlfaXNfY29kZSkKICAgICAgKSwKICAgIGJ5ID0gImZmaV9pc19jb2RlIgogICkKCmZmaV90b3RhbCA8LSBmZmlfdG90YWwgJT4lCiAgbXV0YXRlKAogICAgYWdlX2NhdCA9IGNhc2Vfd2hlbigKICAgICAgZmZpX2lzX2FnZV9maXhlZCA+PSA3MCB+ICJbNzArKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gNjAgfiAiWzYwLTcwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gNTAgfiAiWzUwLTYwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gNDAgfiAiWzQwLTUwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gMzAgfiAiWzMwLTQwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gMjAgfiAiWzIwLTMwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gMTAgfiAiWzEwLTIwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gMCB+ICJbMC0xMCkiCiAgICApLAogICAgYWdlX2NhdCA9IGZhY3RvcihhZ2VfY2F0KSwKICAgIGFnZV9jb2RlID0gY2FzZV93aGVuKAogICAgICBhZ2VfY2F0ID09ICJbNzArKSIgfiA4LAogICAgICBhZ2VfY2F0ID09ICJbNjAtNzApIiB+IDcsCiAgICAgIGFnZV9jYXQgPT0gIls1MC02MCkiIH4gNiwKICAgICAgYWdlX2NhdCA9PSAiWzQwLTUwKSIgfiA1LAogICAgICBhZ2VfY2F0ID09ICJbMzAtNDApIiB+IDQsCiAgICAgIGFnZV9jYXQgPT0gIlsyMC0zMCkiIH4gMywKICAgICAgYWdlX2NhdCA9PSAiWzEwLTIwKSIgfiAyLAogICAgICBhZ2VfY2F0ID09ICJbMC0xMCkiIH4gMSwKICAgICksCiAgICBnZW5kZXIgPSBmYWN0b3IoCiAgICAgIGZmaV9pc19zZXgsCiAgICAgIGxhYmVscyA9IGMoIk1hbGUiLCAiRmVtYWxlIikKICAgICksCiAgICBmZmlfaXNfbWFsYXJpYSA9IGZhY3RvcigKICAgICAgZmZpX2lzX21hbGFyaWEsCiAgICAgIGxhYmVscyA9IGMoIk5vIiwgIlllcyIsICJEb24ndCBLbm93IC8gTm8gQW5zd2VyIikKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMocGZfcmVjZW50OnB2X2hpc3RvcmljKSwKICAgICAgfiBmYWN0b3IoLiwgbGFiZWxzID0gYygiTmVnYXRpdmUiLCAiUG9zaXRpdmUiKSkKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMoCiAgICAgICAgZmZpX2lzX2ZldmVyX21vbnRoLAogICAgICAgIGZmaV9pc19hbnRpbWFsX2RydWdfdXNlLCAKICAgICAgICBmZmlfaXNfbW9zcV9uZXQKICAgICAgKSwKICAgICAgfiBmYWN0b3IoLiwgbGFiZWxzID0gYygiTm8iLCAiWWVzIikpCiAgICApLAogICAgZmZpX2lzX3RyaXBfbW9udGggPSBmYWN0b3IoCiAgICAgIGZmaV9pc190cmlwX21vbnRoLAogICAgICBsYWJlbHMgPSBjKCJObyIsICJZZXMiLCAiRG9uJ3QgS25vdy9ObyBBbnN3ZXIiKQogICAgKSwKICAgIGZmaV9pc19tYWxfbGlmZXRpbWUgPSBmYWN0b3IoCiAgICAgIGZmaV9pc19tYWxfbGlmZXRpbWUsCiAgICAgIGxhYmVscyA9IGMoCiAgICAgICAgIjEgdG8gMyB0aW1lcyIsCiAgICAgICAgIjMgdG8gNyB0aW1lcyIsCiAgICAgICAgIk1vcmUgdGhhbiA3IHRpbWVzIgogICAgICApCiAgICApLAogICAgZmZpX2lzX3BsYWNlX3Nob3dlciA9IGZhY3RvcigKICAgICAgZmZpX2lzX3BsYWNlX3Nob3dlciwKICAgICAgbGFiZWxzID0gYygKICAgICAgICAiQmF0aHJvb20gaW5zaWRlIHRoZSBkd2VsbGluZyIsCiAgICAgICAgIkJhdGhyb29tIG91dHNpZGUgdGhlIGR3ZWxsaW5nIiwKICAgICAgICAiSW4gdGhlIGNvdW50cnlzaWRlL3JpdmVyIiwKICAgICAgICAiT3RoZXIiCiAgICAgICkKICAgICksCiAgICBlZHVjYXRpb25fbGV2ZWwgPSBjYXNlX3doZW4oCiAgICAgIGZmaV9pc19pbnN0X2xldmVsICVpbiUgMCB+ICJObyBzY2hvb2xpbmciLCAKICAgICAgZmZpX2lzX2luc3RfbGV2ZWwgJWluJSAxOjIgfiAiUHJpbWFyeSBzY2hvb2wiLAogICAgICBmZmlfaXNfaW5zdF9sZXZlbCAlaW4lIDM6NCB+ICJTZWNvbmRhcnkgc2Nob29sIiwKICAgICAgZmZpX2lzX2luc3RfbGV2ZWwgJWluJSA1OjYgfiAiSGlnaGVyIGVkdWNhdGlvbiIKICAgICksCiAgICBlZHVjYXRpb25fbGV2ZWwgPSBmY3RfcmVsZXZlbChlZHVjYXRpb25fbGV2ZWwsICJObyBzY2hvb2xpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByaW1hcnkgc2Nob29sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZWNvbmRhcnkgc2Nob29sIiksCiAgICBlY29ub21pY19hY3Rpdml0aWVzID0gZmFjdG9yKGZmaV9pc19tYWluX2Vjb25fYWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJEYXkgbGFib3VyZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXb29kIGV4dHJhY3RvciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZpc2hlcm1hbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxpdmVzdG9jayBmYXJtZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYXJtZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUcmFkZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIb3VzZXdpZmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdHVkZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTW90b3JjeWNsZSB0YXhpIGRyaXZlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vbmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPdGhlciIpKSwKICAgIHB2X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBwdl9yZWNlbnQgPT0gIk5lZ2F0aXZlIiAmIHB2X2hpc3RvcmljID09ICJOZWdhdGl2ZSIgfiAiTmVnYXRpdmUiLAogICAgICBpcy5uYShwdl9yZWNlbnQpICYgaXMubmEocHZfaGlzdG9yaWMpIH4gTkFfY2hhcmFjdGVyXywKICAgICAgVFJVRSB+ICJQb3NpdGl2ZSIKICAgICksCiAgICBwZl9leHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgcGZfcmVjZW50ID09ICJOZWdhdGl2ZSIgJiBwZl9oaXN0b3JpYyA9PSAiTmVnYXRpdmUiIH4gIk5lZ2F0aXZlIiwKICAgICAgaXMubmEocGZfcmVjZW50KSAmIGlzLm5hKHBmX2hpc3RvcmljKSB+IE5BX2NoYXJhY3Rlcl8sCiAgICAgIFRSVUUgfiAiUG9zaXRpdmUiCiAgICApLAogICAgcmVjZW50X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBwdl9yZWNlbnQgPT0gIk5lZ2F0aXZlIiAmIHBmX3JlY2VudCA9PSAiTmVnYXRpdmUiIH4gIk5lZ2F0aXZlIiwKICAgICAgaXMubmEocHZfcmVjZW50KSAmIGlzLm5hKHBmX3JlY2VudCkgfiBOQV9jaGFyYWN0ZXJfLAogICAgICBUUlVFIH4gIlBvc2l0aXZlIgogICAgKSwKICAgIGhpc3RvcmljYWxfZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIHB2X2hpc3RvcmljID09ICJOZWdhdGl2ZSIgJiBwZl9oaXN0b3JpYyA9PSAiTmVnYXRpdmUiIH4gIk5lZ2F0aXZlIiwKICAgICAgaXMubmEocHZfaGlzdG9yaWMpICYgaXMubmEocGZfaGlzdG9yaWMpIH4gTkFfY2hhcmFjdGVyXywKICAgICAgVFJVRSB+ICJQb3NpdGl2ZSIKICAgICksCiAgICBvbmx5X3B2X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBwdl9leHBvc3VyZSA9PSAiUG9zaXRpdmUiICYgcGZfZXhwb3N1cmUgPT0gIk5lZ2F0aXZlIiB+ICJQb3NpdGl2ZSIsIAogICAgICBUUlVFIH4gIk5lZ2F0aXZlIgogICAgKSwKICAgIG9ubHlfcGZfZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIHBmX2V4cG9zdXJlID09ICJQb3NpdGl2ZSIgJiBwdl9leHBvc3VyZSA9PSAiTmVnYXRpdmUiIH4gIlBvc2l0aXZlIiwgCiAgICAgIFRSVUUgfiAiTmVnYXRpdmUiCiAgICApLAogICAgcHZfcGZfZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIHB2X2V4cG9zdXJlID09ICJQb3NpdGl2ZSIgJiBwZl9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gIlBvc2l0aXZlIiwKICAgICAgVFJVRSB+ICJOZWdhdGl2ZSIKICAgICksCiAgICBmcmVlZG9tX21hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIHB2X2V4cG9zdXJlID09ICJOZWdhdGl2ZSIgJiBwZl9leHBvc3VyZSA9PSAiTmVnYXRpdmUiIH4gIlBvc2l0aXZlIiwgCiAgICAgIFRSVUUgfiAiTmVnYXRpdmUiCiAgICApLAogICAgb25seV9wdl9yZWNlbnQgPSBjYXNlX3doZW4oCiAgICAgIHB2X3JlY2VudCA9PSAiUG9zaXRpdmUiICYgcGZfcmVjZW50ID09ICJOZWdhdGl2ZSIgfiAiUG9zaXRpdmUiLCAKICAgICAgVFJVRSB+ICJOZWdhdGl2ZSIKICAgICksCiAgICBvbmx5X3BmX3JlY2VudCA9IGNhc2Vfd2hlbigKICAgICAgcGZfcmVjZW50ID09ICJQb3NpdGl2ZSIgJiBwdl9yZWNlbnQgPT0gIk5lZ2F0aXZlIiB+ICJQb3NpdGl2ZSIsIAogICAgICBUUlVFIH4gIk5lZ2F0aXZlIgogICAgKSwKICAgIHB2X3BmX3JlY2VudCA9IGNhc2Vfd2hlbigKICAgICAgcHZfcmVjZW50ID09ICJQb3NpdGl2ZSIgJiBwZl9yZWNlbnQgPT0gIlBvc2l0aXZlIiB+ICJQb3NpdGl2ZSIsCiAgICAgIFRSVUUgfiAiTmVnYXRpdmUiCiAgICApLAogICAgZnJlZWRvbV9tYWxhcmlhX3JlY2VudCA9IGNhc2Vfd2hlbigKICAgICAgcHZfcmVjZW50ID09ICJOZWdhdGl2ZSIgJiBwZl9yZWNlbnQgPT0gIk5lZ2F0aXZlIiB+ICJQb3NpdGl2ZSIsIAogICAgICBUUlVFIH4gIk5lZ2F0aXZlIgogICAgKSwKICAgIG9ubHlfcHZfaGlzdG9yaWMgPSBjYXNlX3doZW4oCiAgICAgIHB2X2hpc3RvcmljID09ICJQb3NpdGl2ZSIgJiBwZl9oaXN0b3JpYyA9PSAiTmVnYXRpdmUiIH4gIlBvc2l0aXZlIiwgCiAgICAgIFRSVUUgfiAiTmVnYXRpdmUiCiAgICApLAogICAgb25seV9wZl9oaXN0b3JpYyA9IGNhc2Vfd2hlbigKICAgICAgcGZfaGlzdG9yaWMgPT0gIlBvc2l0aXZlIiAmIHB2X2hpc3RvcmljID09ICJOZWdhdGl2ZSIgfiAiUG9zaXRpdmUiLCAKICAgICAgVFJVRSB+ICJOZWdhdGl2ZSIKICAgICksCiAgICBwdl9wZl9oaXN0b3JpYyA9IGNhc2Vfd2hlbigKICAgICAgcHZfaGlzdG9yaWMgPT0gIlBvc2l0aXZlIiAmIHBmX2hpc3RvcmljID09ICJQb3NpdGl2ZSIgfiAiUG9zaXRpdmUiLAogICAgICBUUlVFIH4gIk5lZ2F0aXZlIgogICAgKSwKICAgIGZyZWVkb21fbWFsYXJpYV9oaXN0b3JpYyA9IGNhc2Vfd2hlbigKICAgICAgcHZfaGlzdG9yaWMgPT0gIk5lZ2F0aXZlIiAmIHBmX2hpc3RvcmljID09ICJOZWdhdGl2ZSIgfiAiUG9zaXRpdmUiLCAKICAgICAgVFJVRSB+ICJOZWdhdGl2ZSIKICAgICksCiAgICBhY3Jvc3MoYyhwdl9leHBvc3VyZTpmcmVlZG9tX21hbGFyaWFfaGlzdG9yaWMpLCBmYWN0b3IpCiAgKQoKbGFiZWxsZWQ6OnZhcl9sYWJlbChmZmlfdG90YWwpIDwtIGxpc3QoCiAgZmZpX2lzX2Rpc3RyaWN0ID0gIkRpc3RyaWNzIiwKICBnZW5kZXIgPSAiR2VuZGVyIiwKICBhZ2VfY2F0ID0gIkFnZSIsCiAgZWR1Y2F0aW9uX2xldmVsID0gIkVkdWNhdGlvbiBMZXZlbCIsCiAgZWNvbm9taWNfYWN0aXZpdGllcyA9ICJFY29ub21pYyBBY3Rpdml0aWVzIiwKICBwZl9yZWNlbnQgPSAiUmVjZW50IFAuIEZhbGNpcGFydW0iLAogIHBmX2hpc3RvcmljID0gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgcHZfcmVjZW50ID0gIlJlY2VudCBQLiBWaXZheCIsCiAgcHZfaGlzdG9yaWMgPSAiSGlzdG9yaWNhbCBQLiBWaXZheCIsCiAgcHZfZXhwb3N1cmUgPSAiUC4gVml2YXggRXhwb3N1cmUiLAogIHBmX2V4cG9zdXJlID0gIlAuIEZhbGNpcGFydW0gRXhwb3N1cmUiCikKYGBgCgpgYGB7ciBldmFsID0gRkFMU0V9CnNhdmVSRFMoZmZpX3RvdGFsLCAKICAgICAgICBmaWxlID0gIjAxX2RhdGEvcHJvY2Vzc2VkL2ZmaV90b3RhbC5yZHMiKQpgYGAKCiMgVGFibGUgZGVzY3JpcHRpdmUKCmBgYHtyfQpsaWJyYXJ5KGd0c3VtbWFyeSkKCmZpc2hlci50ZXN0LnNpbXVsYXRlLnAudmFsdWVzIDwtIGZ1bmN0aW9uKGRhdGEsIHZhcmlhYmxlLCBieSwgLi4uKSB7CiAgcmVzdWx0IDwtIGxpc3QoKQogIHRlc3RfcmVzdWx0cyA8LSBzdGF0czo6ZmlzaGVyLnRlc3QoZGF0YVtbdmFyaWFibGVdXSwgZGF0YVtbYnldXSwgc2ltdWxhdGUucC52YWx1ZSA9IFRSVUUpCiAgcmVzdWx0JHAgPC0gdGVzdF9yZXN1bHRzJHAudmFsdWUKICByZXN1bHQkdGVzdCA8LSB0ZXN0X3Jlc3VsdHMkbWV0aG9kCiAgcmVzdWx0Cn0KYGBgCgojIyBUYWJsZSBmb3IgZGlzdHJpY3QKCmBgYHtyfQp0YWJsZV8xIDwtIGZmaV90b3RhbCAlPiUKICBzZWxlY3QoCiAgICBmZmlfaXNfZGlzdHJpY3QsCiAgICBnZW5kZXIsCiAgICBhZ2VfY2F0LAogICAgZWR1Y2F0aW9uX2xldmVsLAogICAgZWNvbm9taWNfYWN0aXZpdGllcywKICAgIHBmX3JlY2VudDpwdl9oaXN0b3JpYwogICkgJT4lCiAgdGJsX3N1bW1hcnkoCiAgICBieSA9ICJmZmlfaXNfZGlzdHJpY3QiLAogICAgbWlzc2luZ190ZXh0ID0gIk1pc3NpbmciCiAgKSAlPiUKICBhZGRfbigpICU+JQogIGFkZF9vdmVyYWxsKCkgJT4lCiAgYWRkX3AoCiAgICAgdGVzdCA9IGxpc3QoYWxsX2NhdGVnb3JpY2FsKCkgfiAiZmlzaGVyLnRlc3Quc2ltdWxhdGUucC52YWx1ZXMiKQogICkgJT4lIAogIGJvbGRfcCgpICU+JQogIG1vZGlmeV9oZWFkZXIobGFiZWwgPSAiKipWYXJpYWJsZSoqIikgJT4lCiAgYm9sZF9sYWJlbHMoKQogIAp0YWJsZTEKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQp0YWJsZV8xICU+JQogIGFzX2ZsZXhfdGFibGUoKSAlPiUKICBmbGV4dGFibGU6OnNhdmVfYXNfZG9jeChwYXRoID0gIi4vMDJfb3V0cHV0L3JlcG9ydHMvdGFibGUxLmRvY3giKQpgYGAKCiMjIFRhYmxlIGZvciBQbGFzbW9kaXVtCmBgYHtyfQogdGFibGUyIDwtIGZmaV90b3RhbCAlPiUKICAgc2VsZWN0KAogICAgIGdlbmRlciwKICAgICBhZ2VfY2F0LAogICAgIGVkdWNhdGlvbl9sZXZlbCwKICAgICBlY29ub21pY19hY3Rpdml0aWVzLAogICAgIHBmX2V4cG9zdXJlLAogICAgIHB2X2V4cG9zdXJlCiAgICkgJT4lCiAgIGRyb3BfbmEocGZfZXhwb3N1cmUsIHB2X2V4cG9zdXJlKSAlPiUKICAgcGl2b3RfbG9uZ2VyKAogICAgIGNvbHMgPSBwdl9leHBvc3VyZTpwZl9leHBvc3VyZSwKICAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICAgdmFsdWVzX3RvID0gInJlc3VsdF9leHBvc3VyZSIKICAgKSAlPiUKICAgbXV0YXRlKAogICAgZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIGV4cG9zdXJlID09ICJwdl9leHBvc3VyZSIgfiAiUC4gVml2YXggRXhwb3N1cmUiLAogICAgICBleHBvc3VyZSA9PSAicGZfZXhwb3N1cmUiIH4gIlAuIEZhbGNpcGFydW0gRXhwb3N1cmUiCiAgICApCiAgICkgJT4lCiAgIHRibF9zdHJhdGEoCiAgICBzdHJhdGEgPSBleHBvc3VyZSwKICAgIC50YmxfZnVuID0KICAgICAgfiAueCAlPiUKICAgICAgICAgIHRibF9zdW1tYXJ5KAogICAgICAgICAgICBieSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgICAgICAgbWlzc2luZ190ZXh0ID0gIk1pc3NpbmciCiAgICAgICAgICApICU+JQogICAgICAgICAgYWRkX3AoCiAgICAgICAgICAgIHRlc3QgPSBsaXN0KGFsbF9jYXRlZ29yaWNhbCgpIH4gImZpc2hlci50ZXN0LnNpbXVsYXRlLnAudmFsdWVzIikKICAgICAgICAgICkgJT4lCiAgICAgICAgICBib2xkX3AoKSAlPiUKICAgICAgICAgIG1vZGlmeV9oZWFkZXIobGFiZWwgPSAiKipWYXJpYWJsZSoqIikgJT4lCiAgICAgICAgICBib2xkX2xhYmVscygpIAogICApIAoKdGFibGUyX292ZXJhbGwgPC0gZmZpX3RvdGFsICU+JQogIHNlbGVjdCgKICAgIGdlbmRlciwKICAgIGFnZV9jYXQsCiAgICBlZHVjYXRpb25fbGV2ZWwsCiAgICBlY29ub21pY19hY3Rpdml0aWVzLAogICAgcGZfZXhwb3N1cmUsCiAgICBwdl9leHBvc3VyZQogICkgJT4lCiAgZHJvcF9uYShwZl9leHBvc3VyZSwgcHZfZXhwb3N1cmUpICU+JQogIHRibF9zdW1tYXJ5KAogICAgbWlzc2luZ190ZXh0ID0gIk1pc3NpbmciCiAgKSAlPiUKICBtb2RpZnlfaGVhZGVyKAogICAgbGFiZWwgPSAiKipWYXJpYWJsZSoqIgogICkgJT4lCiAgYm9sZF9sYWJlbHMoKSAlPiUKICBtb2RpZnlfc3Bhbm5pbmdfaGVhZGVyKHN0YXRfMCB+ICIqKk92ZXJhbGwqKiIpCgp0YWJsZTIgPC0gdGJsX21lcmdlKAogIHRibHMgPSBsaXN0KHRhYmxlMiwgdGFibGUyX292ZXJhbGwpLAogIHRhYl9zcGFubmVyID0gRkFMU0UKKQoKdGFibGUyCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KdGFibGUyICU+JQogIGFzX2ZsZXhfdGFibGUoKSAlPiUKICBmbGV4dGFibGU6OnNhdmVfYXNfZG9jeChwYXRoID0gIi4vMDJfb3V0cHV0L3JlcG9ydHMvdGFibGUyLmRvY3giKQpgYGAKCiMjIFRhYmxlIGZvciBFeHBvc3VyZSBUaW1lCgpgYGB7cn0KIHRhYmxlMyA8LSBmZmlfdG90YWwgJT4lCiAgIHNlbGVjdCgKICAgICBnZW5kZXIsCiAgICAgYWdlX2NhdCwKICAgICBlZHVjYXRpb25fbGV2ZWwsCiAgICAgZWNvbm9taWNfYWN0aXZpdGllcywKICAgICByZWNlbnRfZXhwb3N1cmUsCiAgICAgaGlzdG9yaWNhbF9leHBvc3VyZQogICApICU+JQogICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSkgJT4lCiAgIHBpdm90X2xvbmdlcigKICAgICBjb2xzID0gcmVjZW50X2V4cG9zdXJlOmhpc3RvcmljYWxfZXhwb3N1cmUsCiAgICAgbmFtZXNfdG8gPSAiZXhwb3N1cmUiLAogICAgIHZhbHVlc190byA9ICJyZXN1bHRfZXhwb3N1cmUiCiAgICkgJT4lCiAgIG11dGF0ZSgKICAgIGV4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBleHBvc3VyZSA9PSAicmVjZW50X2V4cG9zdXJlIiB+ICJSZWNlbnQgRXhwb3N1cmUiLAogICAgICBleHBvc3VyZSA9PSAiaGlzdG9yaWNhbF9leHBvc3VyZSIgfiAiSGlzdG9yaWNhbCBFeHBvc3VyZSIKICAgICkKICAgKSAlPiUKICAgdGJsX3N0cmF0YSgKICAgIHN0cmF0YSA9IGV4cG9zdXJlLAogICAgLnRibF9mdW4gPQogICAgICB+IC54ICU+JQogICAgICAgICAgdGJsX3N1bW1hcnkoCiAgICAgICAgICAgIGJ5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICAgICAgICBtaXNzaW5nX3RleHQgPSAiTWlzc2luZyIKICAgICAgICAgICkgJT4lCiAgICAgICAgICBhZGRfcCgKICAgICAgICAgICAgdGVzdCA9IGxpc3QoYWxsX2NhdGVnb3JpY2FsKCkgfiAiZmlzaGVyLnRlc3Quc2ltdWxhdGUucC52YWx1ZXMiKQogICAgICAgICAgKSAlPiUKICAgICAgICAgIGJvbGRfcCgpICU+JQogICAgICAgICAgbW9kaWZ5X2hlYWRlcihsYWJlbCA9ICIqKlZhcmlhYmxlKioiKSAlPiUKICAgICAgICAgIGJvbGRfbGFiZWxzKCkgCiAgICkgCgp0YWJsZTNfb3ZlcmFsbCA8LSBmZmlfdG90YWwgJT4lCiAgc2VsZWN0KAogICAgZ2VuZGVyLAogICAgYWdlX2NhdCwKICAgIGVkdWNhdGlvbl9sZXZlbCwKICAgIGVjb25vbWljX2FjdGl2aXRpZXMsCiAgICByZWNlbnRfZXhwb3N1cmUsCiAgICBoaXN0b3JpY2FsX2V4cG9zdXJlCiAgKSAlPiUKICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSkgJT4lCiAgdGJsX3N1bW1hcnkoCiAgICBtaXNzaW5nX3RleHQgPSAiTWlzc2luZyIKICApICU+JQogIG1vZGlmeV9oZWFkZXIoCiAgICBsYWJlbCA9ICIqKlZhcmlhYmxlKioiCiAgKSAlPiUKICBib2xkX2xhYmVscygpICU+JQogIG1vZGlmeV9zcGFubmluZ19oZWFkZXIoc3RhdF8wIH4gIioqT3ZlcmFsbCoqIikKCnRhYmxlMyA8LSB0YmxfbWVyZ2UoCiAgdGJscyA9IGxpc3QodGFibGUzLCB0YWJsZTNfb3ZlcmFsbCksCiAgdGFiX3NwYW5uZXIgPSBGQUxTRQopCgp0YWJsZTMKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQp0YWJsZTMgJT4lCiAgYXNfZmxleF90YWJsZSgpICU+JQogIGZsZXh0YWJsZTo6c2F2ZV9hc19kb2N4KHBhdGggPSAiLi8wMl9vdXRwdXQvcmVwb3J0cy90YWJsZTMuZG9jeCIpCmBgYAoKCiMgRGlzdGFuY2UgY29tbXVuaXRpZXMgYW5kIHJlZ2lvbmFsIEhvc3BpdGFsCgpgYGB7cn0KaXF1aXRvc19jZW50cm8gPC0gdGliYmxlKAogICJmZmlfaF9oZWFsdGhfZmFjaWxpdHlfbmFtZSIgPSAiSG9zcGl0YWwgUmVnaW9uYWwgZGUgTG9yZXRvIiwKICBMb25naXR1ZGUgPSAtNzMuMjUzODU5MDIwODA5MDYsCiAgTGF0aXR1ZGUgPSAtMy43MjY0MDYwMTY0MTQ4NzE2LAopICU+JQogIHN0X2FzX3NmKGNvb3JkcyA9IGMoIkxvbmdpdHVkZSIsICJMYXRpdHVkZSIpLCBjcnMgPSA0MzI2KSAlPiUKICBzdF90cmFuc2Zvcm0oY3JzID0gMzI3MTgpCgpjb21tdW5pdGllc19zZiA8LSBmZmlfaG91c2Vob2xkICU+JQogIHNlbGVjdCgKICAgIGZmaV9oX2Rpc3RyaWN0LAogICAgZmZpX2hfY29kZV9jb21tdW5pdHksCiAgICBmZmlfaF9jb21tdW5pdHksCiAgICBmZmlfZ3BzX2xvbmcsCiAgICBmZmlfZ3BzX2xhdAogICkgJT4lCiAgc3RfYXNfc2YoCiAgICBjb29yZHMgPSBjKCJmZmlfZ3BzX2xvbmciLCAiZmZpX2dwc19sYXQiKSwKICAgIGNycyA9IDQzMjYKICApICU+JQogIGdyb3VwX2J5KGZmaV9oX2Rpc3RyaWN0LCBmZmlfaF9jb2RlX2NvbW11bml0eSwgZmZpX2hfY29tbXVuaXR5KSAlPiUKICBzdW1tYXJpc2UoKSAlPiUKICBzdF9jZW50cm9pZCgpCiAgCgpjb21tdW5pdGllc19kaXN0YW5jZXMgPC0gY29tbXVuaXRpZXNfc2YgJT4lCiAgc3RfdHJhbnNmb3JtKGNycyA9IDMyNzE4KSAlPiUKICBzdF9kaXN0YW5jZShpcXVpdG9zX2NlbnRybykKCmNvbW11bml0aWVzX2Rpc3RhbmNlcyA8LSBlbmZyYW1lKGNvbW11bml0aWVzX2Rpc3RhbmNlcykgJT4lCiAgbXV0YXRlKAogICAgZmZpX2lzX2NvZF9jb20gPSBjb21tdW5pdGllc19zZiRmZmlfaF9jb2RlX2NvbW11bml0eSwKICAgIGZmaV9pc19jb21tdW5pdHkgPSBjb21tdW5pdGllc19zZiRmZmlfaF9jb21tdW5pdHksCiAgICBkaXN0YW5jZSA9IGFzLm51bWVyaWModmFsdWUpCiAgKSAlPiUKICBzZWxlY3QoLWMobmFtZSwgdmFsdWUpKQpgYGAKCkxhcyBDb211bmlkYWRlcyBtYXMgY2VyY2FuYXMgeSBtYXMgbGVqYW5hcyBwb3IgZGlzdHJpdG86CgpgYGB7ciBldmFsPUZBTFNFfQpjb21tdW5pdGllc19kaXN0YW5jZXMgJT4lCiAgbXV0YXRlKAogICAgZmZpX2hfZGlzdHJpY3QgPSBjb21tdW5pdGllc19zZiRmZmlfaF9kaXN0cmljdAogICkgJT4lCiAgZ3JvdXBfYnkoZmZpX2hfZGlzdHJpY3QpICU+JQogIHNsaWNlX21pbihkaXN0YW5jZSwgbiA9IDEpICU+JQogIGJpbmRfcm93cygKICAgIGNvbW11bml0aWVzX2Rpc3RhbmNlcyAlPiUKICAgICAgbXV0YXRlKAogICAgICAgIGZmaV9oX2Rpc3RyaWN0ID0gY29tbXVuaXRpZXNfc2YkZmZpX2hfZGlzdHJpY3QKICAgICAgKSAlPiUKICAgICAgZ3JvdXBfYnkoZmZpX2hfZGlzdHJpY3QpICU+JQogICAgICBzbGljZV9tYXgoZGlzdGFuY2UsIG4gPSAxKQogICkgJT4lCiAgYXJyYW5nZShmZmlfaF9kaXN0cmljdCwgZGlzdGFuY2UpCmBgYAoKIyBQbG90cwoKIyMgTWFsYXJpYSBBbm51YWwgUGFyYXNpdGUgSW5kZXgKCgpgYGB7cn0KZGF0YV9tYWxhcmlhIDwtIGJpbmRfcm93cygKICBkYXRhXzIwMDBfMjAxOSwKICBkYXRhXzIwMjBfMjAyMQopICU+JQogIGRyb3BfbmEoRGlzdHJpY3QpCgpwb2JfbG9yZXRvIDwtIHBvYmxhY2lvbiAlPiUKICBmaWx0ZXIoZGVwID09ICJMT1JFVE8iKSAlPiUKICBzZWxlY3QoRGlzdHJpY3QgPSBkaXN0ciwgVG90YWwpCmBgYAoKCmBgYHtyfQptYWxhcmlhX2Nhc2VzX3BvYiA8LSBkYXRhX21hbGFyaWEgJT4lCiAgcm93d2lzZSgpICU+JQogIG11dGF0ZSgKICAgIGNhc2VzX21hbGFyaWEgPSBzdW0oCiAgICAgIGNfYWNyb3NzKGMoCiAgICAgICAgYENvbmZpcm1lZCBQLiBGYWxjaXBhcnVtYCwKICAgICAgICBgQ29uZmlybWVkIFAuIFZpdmF4YAogICAgICApKSwKICAgICAgbmEucm0gPSBUUlVFCiAgICApCiAgKSAlPiUKICBncm91cF9ieShEaXN0cmljdCkgJT4lCiAgc3VtbWFyaXNlKGNhc2VzX21hbGFyaWEgPSBzdW0oY2FzZXNfbWFsYXJpYSkpCgptYWxhcmlhX2Nhc2VzX3BvYiA8LSBtYWxhcmlhX2Nhc2VzX3BvYiAlPiUKICBsZWZ0X2pvaW4oCiAgICBwb2JfbG9yZXRvCiAgKSAlPiUKICBtdXRhdGUoCiAgICBhcGkgPSBjYXNlc19tYWxhcmlhICogMTAwMCAvIFRvdGFsCiAgKQoKZGF0YShQZXJ1LCBwYWNrYWdlID0gImlubm92YXIiKQoKbWFsYXJpYV9jYXNlc19wb2Jfc2YgPC0gUGVydSAlPiUKICBmaWx0ZXIoZGVwID09ICJMT1JFVE8iKSAlPiUKICBzZWxlY3QoRGlzdHJpY3QgPSBkaXN0ciwgZ2VvbWV0cnkpICU+JSAKICByaWdodF9qb2luKAogICAgbWFsYXJpYV9jYXNlc19wb2IKICApCmBgYAoKCmBgYHtyfQpmaWd1cmUxIDwtIGdncGxvdChtYWxhcmlhX2Nhc2VzX3BvYl9zZikgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBhcGksIGdlb21ldHJ5ID0gZ2VvbWV0cnkpKSArCiAgZ2VvbV9zZihkYXRhID0gbWFsYXJpYV9jYXNlc19wb2Jfc2YgJT4lIGRwbHlyOjpmaWx0ZXIoRGlzdHJpY3QgPT0gIkJFTEVOIiksIGNvbG91ciA9ICIjYWE2NDM5IiwgZmlsbCA9IE5BLCBzaXplID0gMS41LCBhZXMoZmlsbCA9IGFwaSwgZ2VvbWV0cnkgPSBnZW9tZXRyeSkpICsKICBnZW9tX3NmKGRhdGEgPSBtYWxhcmlhX2Nhc2VzX3BvYl9zZiAlPiUgZHBseXI6OmZpbHRlcihEaXN0cmljdCA9PSAiSU5ESUFOQSIpLCBjb2xvdXIgPSAiIzI1NmU1ZCIsIGZpbGwgPSBOQSwgc2l6ZSA9IDEuNSwgYWVzKGZpbGwgPSBhcGksIGdlb21ldHJ5ID0gZ2VvbWV0cnkpKSArCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIoCiAgICBuYW1lID0gIkFQSSIsCiAgICBuYS52YWx1ZSA9ICJibGFjayIsCiAgICAjIGxpbWl0cyA9IGMoMCwgNDAwMCksCiAgICBwYWxldHRlID0gIlJkWWxHbiIsCiAgICBkaXJlY3Rpb24gPSAtMSwKICAgIGJyZWFrcyA9IHNjYWxlczo6cHJldHR5X2JyZWFrcyhuID0gNSksCiAgICB2YWx1ZXMgPSBjKAogICAgICAwLAogICAgICAwLjAwMSwKICAgICAgMC4wMDIsCiAgICAgIDAuMDA1LAogICAgICAwLjAwOCwKICAgICAgMC4wMSwKICAgICAgMC4wMiwKICAgICAgMC4wMywKICAgICAgMC4wNSwKICAgICAgMC4xLAogICAgICAwLjYsCiAgICAgIDAuOSwKICAgICAgMQogICAgKQogICkgKwogIGxhYnMoCiAgICB4ID0gTlVMTCwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSBOVUxMCiAgKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBnZW9tX3NmX2xhYmVsX3JlcGVsKAogICAgZGF0YSA9IG1hbGFyaWFfY2FzZXNfcG9iX3NmICU+JSBkcGx5cjo6ZmlsdGVyKERpc3RyaWN0ID09ICJCRUxFTiIpLAogICAgYWVzKGxhYmVsID0gRGlzdHJpY3QpLAogICAgbWluLnNlZ21lbnQubGVuZ3RoID0gMCwKICAgIGZvcmNlID0gMTAwLAogICAgbnVkZ2VfeCA9IC0xLAogICAgc2VlZCA9IDEwLAogICAgY29sb3VyID0gIiNhYTY0MzkiCiAgKSArCiAgZ2VvbV9zZl9sYWJlbF9yZXBlbCgKICAgIGRhdGEgPSBtYWxhcmlhX2Nhc2VzX3BvYl9zZiAlPiUgZHBseXI6OmZpbHRlcihEaXN0cmljdCA9PSAiSU5ESUFOQSIpLAogICAgYWVzKGxhYmVsID0gRGlzdHJpY3QpLAogICAgbWluLnNlZ21lbnQubGVuZ3RoID0gMCwKICAgIGZvcmNlID0gMTAwLAogICAgbnVkZ2VfeCA9IDEsCiAgICBzZWVkID0gMTAsCiAgICBjb2xvdXIgPSAiIzI1NmU1ZCIKICApCgpmaWd1cmUxCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9maWd1cmUxLnBuZyIsCiAgZmlndXJlMSwKICBkZXZpY2UgPSBnckRldmljZXM6OnBuZywKICBkcGkgPSAzMDAKKQpgYGAKCgojIyBTZXJvbG9naWNhbCBSZXN1bHRzCgojIyMgQnkgY29tbXVuaXRpZXMgYW5kIHR5cGUgb2YgcGxhc21vZGl1bS90aW1lCmBgYHtyfQojIGZmaV90b3RhbCAlPiUKIyAgIGdncGxvdChhZXMoCiMgICAgIHggPSBmZmlfaXNfY29tbXVuaXR5LAojICAgICBmaWxsID0gcHZfaGlzdG9yaWMKIyAgICkpICsKIyAgIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwgMC4yNSkpICsKIyAgIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKQoKcGxvdDEgPC0gZmZpX3RvdGFsICU+JQogIGRyb3BfbmEocGZfcmVjZW50OnB2X2hpc3RvcmljKSAlPiUKICBsZWZ0X2pvaW4oCiAgICBjb21tdW5pdGllc19kaXN0YW5jZXMKICApICAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcGZfcmVjZW50OnB2X2hpc3RvcmljLAogICAgbmFtZXNfdG8gPSAibWFsYXJpYSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X21hbGFyaWEiCiAgKSAlPiUKICBtdXRhdGUoCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3JlY2VudCIgfiAiUmVjZW50IFAuIFZpdmF4IiwKICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICApLAogICAgZmZpX2lzX2NvbW11bml0eSA9IHN0cl90b190aXRsZShmZmlfaXNfY29tbXVuaXR5KSwKICAgIGZmaV9pc19jb21tdW5pdHkgPSBwYXN0ZTAoCiAgICAgIGZmaV9pc19jb21tdW5pdHksCiAgICAgICIgKCIsCiAgICAgIHN0cl90b190aXRsZShmZmlfaXNfZGlzdHJpY3QpLAogICAgICAiKSIKICAgICksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gZmN0X3Jlb3JkZXIoCiAgICAgIGZmaV9pc19jb21tdW5pdHksCiAgICAgIGRpc3RhbmNlLAogICAgICAuZGVzYyA9IFRSVUUKICAgICkKICApICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0gZmZpX2lzX2NvbW11bml0eSwKICAgIGZpbGwgPSByZXN1bHRfbWFsYXJpYQogICkpICsKICBmYWNldF93cmFwKHZhcnMobWFsYXJpYSkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIiwgY29sb3IgPSAiYmxhY2siKSArCiAgY29vcmRfZmxpcCh5bGltID0gYygwLCAwLjI1KSkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKQogICkgKwogICNnZ3NjaTo6c2NhbGVfZmlsbF9sYW5jZXQoKSArCiAgaW5ub3Zhcjo6c2NhbGVfZmlsbF9pbm5vdmEoIm5wciIpICsKICBsYWJzKAogICAgeCA9ICJDb21tdW5pdGllcyIsCiAgICB5ID0gIlBlcmNlbnRhZ2UiCiAgKSArCiAgZ3VpZGVzKAogICAgZmlsbCA9IGd1aWRlX2xlZ2VuZCgiUmVzdWx0cyIpCiAgKSArICAKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KAogICAgICBmYWNlID0gImJvbGQiLAogICAgICBzaXplID0gMTEKICAgICkKICApCgpwbG90MQpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDFfdHlwZW9mbWFsYXJpYV9jb21tdW5pdGllcy5wbmciLAogIHBsb3QxLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMCwKICBoZWlnaHQgPSA5CikKYGBgCgoKIyMjIEJ5IGNvbW11bml0aWVzLCBJbmRpYW5hIGFuZCB0eXBlIG9mIHBsYXNtb2RpdW0vdGltZQpgYGB7cn0KcGxvdDFfaW5kaWFuYSA8LSBmZmlfdG90YWwgJT4lCiAgZHJvcF9uYShwZl9yZWNlbnQ6cHZfaGlzdG9yaWMpICU+JQogIGxlZnRfam9pbigKICAgIGNvbW11bml0aWVzX2Rpc3RhbmNlcwogICkgICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsCiAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKICApICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIG1hbGFyaWEgPT0gInBmX3JlY2VudCIgfiAiUmVjZW50IFAuIEZhbGNpcGFydW0iLAogICAgICBtYWxhcmlhID09ICJwZl9oaXN0b3JpYyIgfiAiSGlzdG9yaWNhbCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicHZfcmVjZW50IiB+ICJSZWNlbnQgUC4gVml2YXgiLAogICAgICBtYWxhcmlhID09ICJwdl9oaXN0b3JpYyIgfiAiSGlzdG9yaWNhbCBQLiBWaXZheCIKICAgICksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gc3RyX3RvX3RpdGxlKGZmaV9pc19jb21tdW5pdHkpCiAgKSAlPiUKICBmaWx0ZXIoZmZpX2lzX2Rpc3RyaWN0ID09ICJJTkRJQU5BIikgJT4lCiAgbXV0YXRlKAogICAgZmZpX2lzX2NvbW11bml0eSA9IGZjdF9yZW9yZGVyKAogICAgICBmZmlfaXNfY29tbXVuaXR5LAogICAgICBkaXN0YW5jZSwKICAgICAgLmRlc2MgPSBUUlVFCiAgICApCiAgKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgeCA9IGZmaV9pc19jb21tdW5pdHksCiAgICBmaWxsID0gcmVzdWx0X21hbGFyaWEKICApKSArCiAgZmFjZXRfd3JhcCh2YXJzKG1hbGFyaWEpKSArCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIsIGNvbG9yID0gImJsYWNrIikgKwogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwgMC4yNSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkKICApICsKICAjZ2dzY2k6OnNjYWxlX2ZpbGxfbGFuY2V0KCkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgbGFicygKICAgIHRpdGxlID0gc3RyX3dyYXAoIlNlcm9sb2dpY2FsIHJlc3VsdHMgYnkgcGxhc21vZGl1bSB0eXBlIG9mIG1hbGFyaWEgaW4gdGhlIEluZGlhbmEgRGlzdHJpY3QiLCAxMDApLAogICAgeCA9ICJDb21tdW5pdGllcyIsCiAgICB5ID0gIlBlcmNlbnRhZ2UiCiAgKSArCiAgZ3VpZGVzKAogICAgZmlsbCA9IGd1aWRlX2xlZ2VuZCgiUmVzdWx0cyIpCiAgKSArICAKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KAogICAgICBmYWNlID0gImJvbGQiLAogICAgICBzaXplID0gMTEKICAgICkKICApCgpwbG90MV9pbmRpYW5hCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MV90eXBlb2ZtYWxhcmlhX2NvbW11bml0aWVzX2luZGlhbmEucG5nIiwKICBwbG90MV9pbmRpYW5hLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMCwKICBoZWlnaHQgPSA5CikKYGBgCgoKIyMjIEJ5IGNvbW11bml0aWVzLCBCZWxlbiBhbmQgdHlwZSBvZiBwbGFzbW9kaXVtL3RpbWUKYGBge3J9CnBsb3QxX2JlbGVuIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHBmX3JlY2VudDpwdl9oaXN0b3JpYykgJT4lCiAgbGVmdF9qb2luKAogICAgY29tbXVuaXRpZXNfZGlzdGFuY2VzCiAgKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcGZfcmVjZW50OnB2X2hpc3RvcmljLAogICAgbmFtZXNfdG8gPSAibWFsYXJpYSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X21hbGFyaWEiCiAgKSAlPiUKICBmaWx0ZXIoZmZpX2lzX2Rpc3RyaWN0ID09ICJCRUxFTiIpICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIG1hbGFyaWEgPT0gInBmX3JlY2VudCIgfiAiUmVjZW50IFAuIEZhbGNpcGFydW0iLAogICAgICBtYWxhcmlhID09ICJwZl9oaXN0b3JpYyIgfiAiSGlzdG9yaWNhbCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicHZfcmVjZW50IiB+ICJSZWNlbnQgUC4gVml2YXgiLAogICAgICBtYWxhcmlhID09ICJwdl9oaXN0b3JpYyIgfiAiSGlzdG9yaWNhbCBQLiBWaXZheCIKICAgICksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gc3RyX3RvX3RpdGxlKGZmaV9pc19jb21tdW5pdHkpLAogICAgZmZpX2lzX2NvbW11bml0eSA9IGZjdF9yZW9yZGVyKAogICAgICBmZmlfaXNfY29tbXVuaXR5LAogICAgICBkaXN0YW5jZSwKICAgICAgLmRlc2MgPSBUUlVFCiAgICApCiAgKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgeCA9IGZmaV9pc19jb21tdW5pdHksCiAgICBmaWxsID0gcmVzdWx0X21hbGFyaWEKICApKSArCiAgZmFjZXRfd3JhcCh2YXJzKG1hbGFyaWEpKSArCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIsIGNvbG9yID0gImJsYWNrIikgKwogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwgMC4yNSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkKICApICsKICAjZ2dzY2k6OnNjYWxlX2ZpbGxfbGFuY2V0KCkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgbGFicygKICAgIHRpdGxlID0gc3RyX3dyYXAoIlNlcm9sb2dpY2FsIHJlc3VsdHMgYnkgcGxhc21vZGl1bSB0eXBlIG9mIG1hbGFyaWEgaW4gdGhlIEJlbGVuIERpc3RyaWN0IiwgMTAwKSwKICAgIHggPSAiQ29tbXVuaXRpZXMiLAogICAgeSA9ICJQZXJjZW50YWdlIgogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIlJlc3VsdHMiKQogICkgKyAgCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApCiAgKQoKcGxvdDFfYmVsZW4KYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QxX3R5cGVvZm1hbGFyaWFfY29tbXVuaXRpZXNfYmVsZW4ucG5nIiwKICBwbG90MV9iZWxlbiwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTAsCiAgaGVpZ2h0ID0gOQopCmBgYAoKIyMjIEJ5IGNvbW11bml0aWVzLCB0eXBlIG9mIHBsYXNtb2RpdW0gZXhwb3N1cmUKYGBge3J9CnBsb3QyIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHBmX2V4cG9zdXJlLCBwdl9leHBvc3VyZSkgJT4lCiAgbGVmdF9qb2luKAogICAgY29tbXVuaXRpZXNfZGlzdGFuY2VzCiAgKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcHZfZXhwb3N1cmU6cGZfZXhwb3N1cmUsCiAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICkgICU+JQogIG11dGF0ZSgKICAgIGV4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICAgICBleHBvc3VyZSA9PSAicHZfZXhwb3N1cmUiIH4gIlAuIFZpdmF4IEV4cG9zdXJlIiwKICAgICAgICAgZXhwb3N1cmUgPT0gInBmX2V4cG9zdXJlIiB+ICJQLiBGYWxjaXBhcnVtIEV4cG9zdXJlIgogICAgKSwKICAgIGZmaV9pc19jb21tdW5pdHkgPSBzdHJfdG9fdGl0bGUoZmZpX2lzX2NvbW11bml0eSksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gZmN0X3Jlb3JkZXIoCiAgICAgIGZmaV9pc19jb21tdW5pdHksCiAgICAgIGRpc3RhbmNlLAogICAgICAuZGVzYyA9IFRSVUUKICAgICkKICApICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0gZmZpX2lzX2NvbW11bml0eSwKICAgIGZpbGwgPSByZXN1bHRfZXhwb3N1cmUKICApKSArCiAgZmFjZXRfd3JhcCh2YXJzKGV4cG9zdXJlKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiLCBjb2xvciA9ICJibGFjayIpICsKICBjb29yZF9mbGlwKHlsaW0gPSBjKDAsIDAuNDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpCiAgKSArCiAgIyBnZ3NjaTo6c2NhbGVfZmlsbF9sYW5jZXQoKSArCiAgaW5ub3Zhcjo6c2NhbGVfZmlsbF9pbm5vdmEoIm5wciIpICsKICBsYWJzKAogICAgeCA9ICJDb21tdW5pdGllcyIsCiAgICB5ID0gIlBlcmNlbnRhZ2UiCiAgKSArCiAgZ3VpZGVzKAogICAgZmlsbCA9IGd1aWRlX2xlZ2VuZCgiUmVzdWx0cyIpCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApCiAgKQoKcGxvdDIKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QyX3R5cGVvZm1hbGFyaWFfY29tbXVuaXRpZXMucG5nIiwKICBwbG90MiwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTAsCiAgaGVpZ2h0ID0gOQopCmBgYAoKIyMjIEJ5IGNvbW11bml0aWVzLCB0aW1lIG9mIHBsYXNtb2RpdW0gZXhwb3N1cmUKYGBge3J9CnBsb3QzIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSkgJT4lCiAgbGVmdF9qb2luKAogICAgY29tbXVuaXRpZXNfZGlzdGFuY2VzCiAgKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcmVjZW50X2V4cG9zdXJlOmhpc3RvcmljYWxfZXhwb3N1cmUsCiAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICkgJT4lCiAgbXV0YXRlKAogICAgZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIGV4cG9zdXJlID09ICJyZWNlbnRfZXhwb3N1cmUiIH4gIlJlY2VudCBFeHBvc3VyZSIsCiAgICAgIGV4cG9zdXJlID09ICJoaXN0b3JpY2FsX2V4cG9zdXJlIiB+ICJIaXN0b3JpY2FsIEV4cG9zdXJlIgogICAgKSwKICAgIGZmaV9pc19jb21tdW5pdHkgPSBzdHJfdG9fdGl0bGUoZmZpX2lzX2NvbW11bml0eSksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gZmN0X3Jlb3JkZXIoCiAgICAgIGZmaV9pc19jb21tdW5pdHksCiAgICAgIGRpc3RhbmNlLAogICAgICAuZGVzYyA9IFRSVUUKICAgICkKICApICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0gZmZpX2lzX2NvbW11bml0eSwKICAgIGZpbGwgPSByZXN1bHRfZXhwb3N1cmUKICApKSArCiAgZmFjZXRfd3JhcCh2YXJzKGV4cG9zdXJlKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiLCBjb2xvciA9ICJibGFjayIpICsKICBjb29yZF9mbGlwKHlsaW0gPSBjKDAsIDAuMzApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpCiAgKSArCiAgIyBnZ3NjaTo6c2NhbGVfZmlsbF9sYW5jZXQoKSArCiAgaW5ub3Zhcjo6c2NhbGVfZmlsbF9pbm5vdmEoIm5wciIpICsKICBsYWJzKAogICAgeCA9ICJDb21tdW5pdGllcyIsCiAgICB5ID0gIlBlcmNlbnRhZ2UiCiAgKSArCiAgZ3VpZGVzKAogICAgZmlsbCA9IGd1aWRlX2xlZ2VuZCgiUmVzdWx0cyIpCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApCiAgKQoKcGxvdDMKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QzX3R5cGVvZm1hbGFyaWFfY29tbXVuaXRpZXMucG5nIiwKICBwbG90MywKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTAsCiAgaGVpZ2h0ID0gOQopCmBgYAoKCmBgYHtyfQojIGZmaV90b3RhbCAlPiUKIyAgIGRyb3BfbmEocGZfcmVjZW50OnB2X2hpc3RvcmljLCBhZ2VfY2F0KSAlPiUKIyAgIHBpdm90X2xvbmdlcigKIyAgICAgY29scyA9IHBmX3JlY2VudDpwdl9oaXN0b3JpYywKIyAgICAgbmFtZXNfdG8gPSAibWFsYXJpYSIsCiMgICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKIyAgICkgJT4lCiMgICBtdXRhdGUoCiMgICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAojICAgICAgIHJlc3VsdF9tYWxhcmlhID09ICJQb3NpdGl2ZSIgfiAxLAojICAgICAgIFRSVUUgfiAwCiMgICAgICksCiMgICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiMgICAgICAgbWFsYXJpYSA9PSAicGZfcmVjZW50IiB+ICJSZWNlbnQgUC4gRmFsY2lwYXJ1bSIsCiMgICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiMgICAgICAgbWFsYXJpYSA9PSAicHZfcmVjZW50IiB+ICJSZWNlbnQgUC4gVml2YXgiLAojICAgICAgIG1hbGFyaWEgPT0gInB2X2hpc3RvcmljIiB+ICJIaXN0b3JpY2FsIFAuIFZpdmF4IgojICAgICApLAojICAgICBmZmlfaXNfY29tbXVuaXR5ID0gc3RyX3RvX3RpdGxlKGZmaV9pc19jb21tdW5pdHkpCiMgICApICU+JQojICAgZ3JvdXBfYnkoZmZpX2lzX2NvbW11bml0eSwgYWdlX2NhdCwgbWFsYXJpYSkgJT4lCiMgICBzdW1tYXJpc2UocmVzdWx0X21hbGFyaWEgPSBtZWFuKHJlc3VsdF9tYWxhcmlhKSkgJT4lCiMgICBnZ3Bsb3QoCiMgICAgIGFlcygKIyAgICAgICB4ID0gYWdlX2NhdCwKIyAgICAgICB5ID0gcmVzdWx0X21hbGFyaWEsCiMgICAgICAgY29sb3IgPSBtYWxhcmlhLAojICAgICAgIGdyb3VwID0gbWFsYXJpYQojICAgICApCiMgICApICsKIyAgIGdlb21fcG9pbnQoKSArCiMgICBnZW9tX2xpbmUoKSArCiMgICBmYWNldF93cmFwKHZhcnMoZmZpX2lzX2NvbW11bml0eSkpICsKIyAgIHRoZW1lX2J3KCkKYGBgCgojIyBTZXJvcG9zaXRpdml0eSA0IG1hbGFyaWEKCiMjIyBCeSBkaXN0cmljdApgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdCA8LSBmZmlfdG90YWwgJT4lCiAgZHJvcF9uYShwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsIGFnZV9jYXQpICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsCiAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKICApICU+JQogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3JlY2VudCIgfiAiUmVjZW50IFAuIFZpdmF4IiwKICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKSAlPiUKICBncm91cF9ieShmZmlfaXNfZGlzdHJpY3QsIGFnZV9jYXQsIG1hbGFyaWEpICU+JQogIHN1bW1hcmlzZShyZXN1bHRfbWFsYXJpYSA9IG1lYW4ocmVzdWx0X21hbGFyaWEpKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X21hbGFyaWEsCiAgICAgIGNvbG9yID0gbWFsYXJpYSwKICAgICAgZ3JvdXAgPSBtYWxhcmlhCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19kaXN0cmljdCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICBsaW1pdHMgPSBjKDAsIDAuNDApCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKCnNlcm9fNG1hbGFyaWFfZGlzdHJpY3QKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3Q0X3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3QucG5nIiwKICBzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0LAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA3LjUKKQpgYGAKCgojIyMgQnkgSGVhbHRoIEZhY2lsaXR5CgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9oZiA8LSBmZmlfdG90YWwgJT4lCiAgZHJvcF9uYShwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsIGFnZV9jYXQpICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsCiAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKICApICU+JQogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3JlY2VudCIgfiAiUmVjZW50IFAuIFZpdmF4IiwKICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApLAogICAgZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lID0gcGFzdGUoCiAgICAgIGZmaV9pc19kaXN0cmljdCwKICAgICAgZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lLAogICAgICBzZXAgPSAiIC0gIgogICAgKQogICkgJT4lCiAgZ3JvdXBfYnkoZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lLCBhZ2VfY2F0LCBtYWxhcmlhKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X21hbGFyaWEgPSBtZWFuKHJlc3VsdF9tYWxhcmlhKSkgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9tYWxhcmlhLAogICAgICBjb2xvciA9IG1hbGFyaWEsCiAgICAgIGdyb3VwID0gbWFsYXJpYQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X3dyYXAodmFycyhmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKyAKICB0aGVtZV9idygpICsKICB0aGVtZSgKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KAogICAgICBhbmdsZSA9IDQ1LAogICAgICB2anVzdCA9IDEsCiAgICAgIGhqdXN0ID0gMQogICAgKQogICkKICAKc2Vyb180bWFsYXJpYV9oZgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDVfc2Vyb180bWFsYXJpYV9oZi5wbmciLAogIHNlcm9fNG1hbGFyaWFfaGYsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEwLAogIGhlaWdodCA9IDcKKQpgYGAKCiMjIFNlb3Bvc2l0aXZpdHkgYnkgVHlwZSBvZiBNYWxhcmlhCgojIyMgQnkgRGlzdHJpY3QKCmBgYHtyfQpmZmlfdHlwZW9mX21hbGFyaWEgPC0gZmZpX3RvdGFsICU+JQogIGRyb3BfbmEocGZfZXhwb3N1cmUsIHB2X2V4cG9zdXJlLCBhZ2VfY2F0KSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcHZfZXhwb3N1cmU6cGZfZXhwb3N1cmUsCiAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICkgJT4lCiAgbXV0YXRlKAogICAgZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIGV4cG9zdXJlID09ICJwdl9leHBvc3VyZSIgfiAiUC4gVml2YXggRXhwb3N1cmUiLAogICAgICBleHBvc3VyZSA9PSAicGZfZXhwb3N1cmUiIH4gIlAuIEZhbGNpcGFydW0gRXhwb3N1cmUiCiAgICApLAogICAgcmVzdWx0X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfZXhwb3N1cmUgPT0gIlBvc2l0aXZlIiB+IDEsCiAgICAgIFRSVUUgfiAwCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0IDwtIGZmaV90eXBlb2ZfbWFsYXJpYSAlPiUKICBncm91cF9ieShmZmlfaXNfZGlzdHJpY3QsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X2V4cG9zdXJlID0gbWVhbihyZXN1bHRfZXhwb3N1cmUpKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19kaXN0cmljdCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICBsaW1pdHMgPSBjKDAsIDAuNDApCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3Q2X3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdC5wbmciLAogIHNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdCwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTIsCiAgaGVpZ2h0ID0gNy41CikKYGBgCgojIyMgQnkgSGVhbHRoIEZhY2lsaXR5CgpgYGB7cn0Kc2Vyb190eXBlb2ZtYWxhcmlhX2hmIDwtIGZmaV90eXBlb2ZfbWFsYXJpYSAlPiUKICBncm91cF9ieShmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X2V4cG9zdXJlID0gbWVhbihyZXN1bHRfZXhwb3N1cmUpKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19oZWFsdGhfZmFjaWxpdHlfbmFtZSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2hmCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90N19zZXJvX3R5cGVvZm1hbGFyaWFfaGYucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfaGYsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEzLAogIGhlaWdodCA9IDkKKQpgYGAKCiMjIFNlcm9wb3NpdGl2aXR5IGJ5IFRpbWUgb2YgRXhwb3N1cmUgCgojIyMgQnkgRGlzdHJpY3QKYGBge3J9CmZmaV90aW1lb2ZtYWxhcmlhIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSwgYWdlX2NhdCkgJT4lCiAgcGl2b3RfbG9uZ2VyKAogICAgY29scyA9IHJlY2VudF9leHBvc3VyZTpoaXN0b3JpY2FsX2V4cG9zdXJlLAogICAgbmFtZXNfdG8gPSAiZXhwb3N1cmUiLAogICAgdmFsdWVzX3RvID0gInJlc3VsdF9leHBvc3VyZSIKICApICU+JQogIG11dGF0ZSgKICAgIGV4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBleHBvc3VyZSA9PSAicmVjZW50X2V4cG9zdXJlIiB+ICJSZWNlbnQgRXhwb3N1cmUiLAogICAgICBleHBvc3VyZSA9PSAiaGlzdG9yaWNhbF9leHBvc3VyZSIgfiAiSGlzdG9yaWNhbCBFeHBvc3VyZSIKICAgICksCiAgICByZXN1bHRfZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIHJlc3VsdF9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMoZmZpX2lzX2NvbW11bml0eTpmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUpLAogICAgICBzdHJfdG9fdGl0bGUKICAgICkKICApCgpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3QgPC0gZmZpX3RpbWVvZm1hbGFyaWEgJT4lCiAgZ3JvdXBfYnkoZmZpX2lzX2Rpc3RyaWN0LCBhZ2VfY2F0LCBleHBvc3VyZSkgJT4lCiAgc3VtbWFyaXNlKHJlc3VsdF9leHBvc3VyZSA9IG1lYW4ocmVzdWx0X2V4cG9zdXJlKSkgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgY29sb3IgPSBleHBvc3VyZSwKICAgICAgZ3JvdXAgPSBleHBvc3VyZQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X3dyYXAodmFycyhmZmlfaXNfZGlzdHJpY3QpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgbGltaXRzID0gYygwLCAwLjQwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90OF9zZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3QucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3QsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDcuNQopCmBgYAoKIyMjIEJ5IEhlYWx0aCBGYWNpbGl0eQoKYGBge3J9CnNlcm9fdGltZW9mbWFsYXJpYV9oZiA8LSBmZmlfdGltZW9mbWFsYXJpYSAlPiUKICBncm91cF9ieShmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X2V4cG9zdXJlID0gbWVhbihyZXN1bHRfZXhwb3N1cmUpKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19oZWFsdGhfZmFjaWxpdHlfbmFtZSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArIAogIHRoZW1lX2J3KCkKICAKc2Vyb190aW1lb2ZtYWxhcmlhX2hmCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90OV9zZXJvX3RpbWVvZm1hbGFyaWFfaGYucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfaGYsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEzLAogIGhlaWdodCA9IDkKKQpgYGAKCiMjIFJlbGF0aW9uIHdpdGggc2V4CgpgYGB7cn0KbGlicmFyeShybGFuZykKCnNlcm9wb3NpdGl2eV9zdW1tYXJpc2UgPC0gZnVuY3Rpb24oZGF0YSwgdHlwZSwgdmFyaWFibGUsIC4uLikgewogIGlmICh0eXBlID09ICI0bWFsYXJpYSIpIHsKICAgIGZmaV90b3RhbCAlPiUKICAgICAgZHJvcF9uYShwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsIHt7IHZhcmlhYmxlIH19LCAuLi4pICU+JQogICAgICBwaXZvdF9sb25nZXIoCiAgICAgICAgY29scyA9IHBmX3JlY2VudDpwdl9oaXN0b3JpYywKICAgICAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgICAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X21hbGFyaWEiCiAgICAgICkgJT4lCiAgICAgIG11dGF0ZSgKICAgICAgICByZXN1bHRfbWFsYXJpYSA9IGNhc2Vfd2hlbigKICAgICAgICAgIHJlc3VsdF9tYWxhcmlhID09ICJQb3NpdGl2ZSIgfiAxLAogICAgICAgICAgVFJVRSB+IDAKICAgICAgICApLAogICAgICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgICAgIG1hbGFyaWEgPT0gInBmX2hpc3RvcmljIiB+ICJIaXN0b3JpY2FsIFAuIEZhbGNpcGFydW0iLAogICAgICAgICAgbWFsYXJpYSA9PSAicHZfcmVjZW50IiB+ICJSZWNlbnQgUC4gVml2YXgiLAogICAgICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICAgICAgKSwKICAgICAgICBhY3Jvc3MoCiAgICAgICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgICAgIHN0cl90b190aXRsZQogICAgICAgICkKICAgICAgKSAlPiUKICAgICAgZ3JvdXBfYnkoZmZpX2lzX2Rpc3RyaWN0LCB7eyB2YXJpYWJsZSB9fSwgLi4uLCBtYWxhcmlhKSAlPiUKICAgICAgc3VtbWFyaXNlKHJlc3VsdF9tYWxhcmlhID0gbWVhbihyZXN1bHRfbWFsYXJpYSkpCiAgfSBlbHNlIGlmICh0eXBlID09ICJ0eXBlb2ZtYWxhcmlhIiApIHsKICAgIGZmaV90b3RhbCAlPiUKICAgICAgZHJvcF9uYShwZl9leHBvc3VyZSwgcHZfZXhwb3N1cmUsIHt7IHZhcmlhYmxlIH19LCAuLi4pICU+JQogICAgICBwaXZvdF9sb25nZXIoCiAgICAgICAgY29scyA9IHB2X2V4cG9zdXJlOnBmX2V4cG9zdXJlLAogICAgICAgIG5hbWVzX3RvID0gImV4cG9zdXJlIiwKICAgICAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICAgICApICU+JQogICAgICBtdXRhdGUoCiAgICAgICAgZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgICAgICBleHBvc3VyZSA9PSAicHZfZXhwb3N1cmUiIH4gIlAuIFZpdmF4IEV4cG9zdXJlIiwKICAgICAgICAgIGV4cG9zdXJlID09ICJwZl9leHBvc3VyZSIgfiAiUC4gRmFsY2lwYXJ1bSBFeHBvc3VyZSIKICAgICAgICApLAogICAgICAgIHJlc3VsdF9leHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgICAgIHJlc3VsdF9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgICAgIFRSVUUgfiAwCiAgICAgICAgKSwKICAgICAgICBhY3Jvc3MoCiAgICAgICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgICAgIHN0cl90b190aXRsZQogICAgICAgICkKICAgICAgKSAlPiUKICAgICAgZ3JvdXBfYnkoZmZpX2lzX2Rpc3RyaWN0LCB7eyB2YXJpYWJsZSB9fSwgLi4uLCBleHBvc3VyZSkgJT4lCiAgICAgIHN1bW1hcmlzZShyZXN1bHRfZXhwb3N1cmUgPSBtZWFuKHJlc3VsdF9leHBvc3VyZSkpCiAgfSBlbHNlIGlmICh0eXBlID09ICJ0aW1lb2ZtYWxhcmlhIikgewogICAgZmZpX3RvdGFsICU+JQogICAgICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSwgCiAgICAgICAgICAgICAge3sgdmFyaWFibGUgfX0sIC4uLikgJT4lCiAgICAgIHBpdm90X2xvbmdlcigKICAgICAgICBjb2xzID0gcmVjZW50X2V4cG9zdXJlOmhpc3RvcmljYWxfZXhwb3N1cmUsCiAgICAgICAgbmFtZXNfdG8gPSAiZXhwb3N1cmUiLAogICAgICAgIHZhbHVlc190byA9ICJyZXN1bHRfZXhwb3N1cmUiCiAgICAgICkgJT4lCiAgICAgIG11dGF0ZSgKICAgICAgICBleHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgICAgIGV4cG9zdXJlID09ICJyZWNlbnRfZXhwb3N1cmUiIH4gIlJlY2VudCBFeHBvc3VyZSIsCiAgICAgICAgICBleHBvc3VyZSA9PSAiaGlzdG9yaWNhbF9leHBvc3VyZSIgfiAiSGlzdG9yaWNhbCBFeHBvc3VyZSIKICAgICAgICApLAogICAgICAgIHJlc3VsdF9leHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgICAgIHJlc3VsdF9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgICAgIFRSVUUgfiAwCiAgICAgICAgKSwKICAgICAgICBhY3Jvc3MoCiAgICAgICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgICAgIHN0cl90b190aXRsZQogICAgICAgICkKICAgICAgKSAlPiUKICAgICAgZ3JvdXBfYnkoZmZpX2lzX2Rpc3RyaWN0LCB7eyB2YXJpYWJsZSB9fSwgLi4uLCBleHBvc3VyZSkgJT4lCiAgICAgIHN1bW1hcmlzZShyZXN1bHRfZXhwb3N1cmUgPSBtZWFuKHJlc3VsdF9leHBvc3VyZSkpICAgICAgCiAgfSAgCn0KYGBgCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF9nZW5kZXIgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgIjRtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgY29sb3IgPSBtYWxhcmlhLAogICAgICBncm91cCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40MCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb180bWFsYXJpYV9kaXN0cmljdF9nZW5kZXIKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QxMF9zZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlci5wbmciLAogIHNlcm9fNG1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUeXBlIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0eXBlb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDExX3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9nZW5kZXIucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0aW1lb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDEyX3Nlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9nZW5kZXIucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIFJlbGF0aW9uIHdpdGggRWR1Y2F0aW9uIExldmVsCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF9lZHVsZXZlbCA8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAiNG1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZWR1Y2F0aW9uX2xldmVsCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9tYWxhcmlhLAogICAgICBjb2xvciA9IG1hbGFyaWEsCiAgICAgIGdyb3VwID0gbWFsYXJpYQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGVkdWNhdGlvbl9sZXZlbCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC40MCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb180bWFsYXJpYV9kaXN0cmljdF9lZHVsZXZlbApgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDEzX3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3RfZWR1bGV2ZWwucG5nIiwKICBzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUeXBlIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZWR1bGV2ZWwgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInR5cGVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZWR1Y2F0aW9uX2xldmVsCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgY29sb3IgPSBleHBvc3VyZSwKICAgICAgZ3JvdXAgPSBleHBvc3VyZQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGVkdWNhdGlvbl9sZXZlbCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MTRfc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLnBuZyIsCiAgc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZWR1bGV2ZWwgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInRpbWVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZWR1Y2F0aW9uX2xldmVsCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgY29sb3IgPSBleHBvc3VyZSwKICAgICAgZ3JvdXAgPSBleHBvc3VyZQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGVkdWNhdGlvbl9sZXZlbCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MTVfc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLnBuZyIsCiAgc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIFJlbGF0aW9uIHdpdGggRmV2ZXIgTW9udGgKCiMjIyMgQnkgNCBtYWxhcmlhCmBgYHtyfQpmZmlfZmV2ZXJfbW9udGggPC0gZmZpX3RvdGFsICU+JQogIGRyb3BfbmEocGZfcmVjZW50OnB2X2hpc3RvcmljLCBhZ2VfY2F0LCBmZmlfaXNfZmV2ZXJfbW9udGgpICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsCiAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKICApICU+JQogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3JlY2VudCIgfiAiUmVjZW50IFAuIFZpdmF4IiwKICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKSAlPiUKICBncm91cF9ieShmZmlfaXNfZmV2ZXJfbW9udGgsIGFnZV9jYXQsIG1hbGFyaWEpICU+JQogIHN1bW1hcmlzZShyZXN1bHRfbWFsYXJpYSA9IG1lYW4ocmVzdWx0X21hbGFyaWEpKQoKCnNlcm9fNG1hbGFyaWFfZmV2ZXJfbW9udGggPC0gZmZpX2ZldmVyX21vbnRoICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IHJlc3VsdF9tYWxhcmlhLAogICAgICB5ID0gYWdlX2NhdCwKICAgICAgZ3JvdXAgPSBhZ2VfY2F0CiAgICApCiAgKSArCiAgZ2VvbV9wYXRoKAogICAgY29sb3IgPSAiI2JkYmRiZCIKICApICsKICBnZW9tX3BvaW50KAogICAgYWVzKGNvbG9yID0gbWFsYXJpYSksCiAgICBzaXplID0gMwogICkgKwogIGZhY2V0X3dyYXAodmFycyhmZmlfaXNfZmV2ZXJfbW9udGgpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC41KQogICkgKwogIGxhYnMoCiAgICB5ID0gIkFnZSIsCiAgICB4ID0gIlNlcm9wb3NpdGl2aXR5IiwKICAgIHRpdGxlID0gc3RyX3dyYXAoIk1hbGFyaWEgc2Vyb3Bvc2l0aXZpdHkgYnkgdHlwZSBvZiBleHBvc3VyZSwgcGxhc21vZGl1bSBhbmQgcHJlc2VuY2Ugb2YgZmV2ZXIgaW4gdGhlIGxhc3QgbW9udGgiLCAxMDApCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QxNl9zZXJvXzRtYWxhcmlhX2ZldmVybW9udGgucG5nIiwKICBzZXJvXzRtYWxhcmlhX2ZldmVyX21vbnRoLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCgojIyMjIEJ5IFR5cGUgb2YgTWFsYXJpYQoKYGBge3J9CmZmaV9mZXZlcl9tb250aF90eXBlb2ZtYWxhcmlhIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHBmX3JlY2VudDpwdl9oaXN0b3JpYywgYWdlX2NhdCwgZmZpX2lzX2ZldmVyX21vbnRoKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcHZfZXhwb3N1cmU6cGZfZXhwb3N1cmUsCiAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICkgJT4lCiAgICBtdXRhdGUoCiAgICAgIGV4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICAgIGV4cG9zdXJlID09ICJwdl9leHBvc3VyZSIgfiAiUC4gVml2YXggRXhwb3N1cmUiLAogICAgICAgIGV4cG9zdXJlID09ICJwZl9leHBvc3VyZSIgfiAiUC4gRmFsY2lwYXJ1bSBFeHBvc3VyZSIKICAgICAgKSwKICAgICAgcmVzdWx0X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICAgIHJlc3VsdF9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgICBUUlVFIH4gMAogICAgICApLAogICAgICBhY3Jvc3MoCiAgICAgICAgYyhmZmlfaXNfY29tbXVuaXR5OmZmaV9pc19oZWFsdGhfZmFjaWxpdHlfbmFtZSksCiAgICAgICAgc3RyX3RvX3RpdGxlCiAgICAgICkKICAgICkgJT4lCiAgICBncm91cF9ieShmZmlfaXNfZmV2ZXJfbW9udGgsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICAgIHN1bW1hcmlzZShyZXN1bHRfZXhwb3N1cmUgPSBtZWFuKHJlc3VsdF9leHBvc3VyZSkpCgpzZXJvX3R5cGVvZm1hbGFyaWFfZmV2ZXJfbW9udGggPC0gZmZpX2ZldmVyX21vbnRoX3R5cGVvZm1hbGFyaWEgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICB5ID0gYWdlX2NhdCwKICAgICAgZ3JvdXAgPSBhZ2VfY2F0CiAgICApCiAgKSArCiAgZ2VvbV9wYXRoKAogICAgY29sb3IgPSAiI2JkYmRiZCIKICApICsKICBnZW9tX3BvaW50KAogICAgYWVzKGNvbG9yID0gZXhwb3N1cmUpLAogICAgc2l6ZSA9IDMKICApICsKICBmYWNldF93cmFwKHZhcnMoZmZpX2lzX2ZldmVyX21vbnRoKSkgKwogIHNjYWxlX3hfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgICMgbGltaXRzID0gYygwLCAwLjUpCiAgKSArCiAgbGFicygKICAgIHkgPSAiQWdlIiwKICAgIHggPSAiU2Vyb3Bvc2l0aXZpdHkiLAogICAgdGl0bGUgPSBzdHJfd3JhcCgiTWFsYXJpYSBzZXJvcG9zaXRpdml0eSBieSB0eXBlIG9mIHBsYXNtb2RpdW0gYW5kIHByZXNlbmNlIG9mIGZldmVyIGluIHRoZSBsYXN0IG1vbnRoIiwgMTAwKQogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MTZfc2Vyb190eXBlb2ZtYWxhcmlhX2ZldmVybW9udGgucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfZmV2ZXJfbW9udGgsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCgpgYGB7cn0KZmZpX2ZldmVyX21vbnRoX3RpbWVvZm1hbGFyaWEgPC0gZmZpX3RvdGFsICU+JQogIGRyb3BfbmEocGZfcmVjZW50OnB2X2hpc3RvcmljLCBhZ2VfY2F0LCBmZmlfaXNfZmV2ZXJfbW9udGgpICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSByZWNlbnRfZXhwb3N1cmU6aGlzdG9yaWNhbF9leHBvc3VyZSwKICAgIG5hbWVzX3RvID0gImV4cG9zdXJlIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfZXhwb3N1cmUiCiAgKSAlPiUKICBtdXRhdGUoCiAgICBleHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgZXhwb3N1cmUgPT0gInJlY2VudF9leHBvc3VyZSIgfiAiUmVjZW50IEV4cG9zdXJlIiwKICAgICAgZXhwb3N1cmUgPT0gImhpc3RvcmljYWxfZXhwb3N1cmUiIH4gIkhpc3RvcmljYWwgRXhwb3N1cmUiCiAgICApLAogICAgcmVzdWx0X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfZXhwb3N1cmUgPT0gIlBvc2l0aXZlIiB+IDEsCiAgICAgIFRSVUUgfiAwCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKSAlPiUKICBncm91cF9ieShmZmlfaXNfZmV2ZXJfbW9udGgsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X2V4cG9zdXJlID0gbWVhbihyZXN1bHRfZXhwb3N1cmUpKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2ZldmVyX21vbnRoIDwtIGZmaV9mZXZlcl9tb250aF90eXBlb2ZtYWxhcmlhICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgeSA9IGFnZV9jYXQsCiAgICAgIGdyb3VwID0gYWdlX2NhdAogICAgKQogICkgKwogIGdlb21fcGF0aCgKICAgIGNvbG9yID0gIiNiZGJkYmQiCiAgKSArCiAgZ2VvbV9wb2ludCgKICAgIGFlcyhjb2xvciA9IGV4cG9zdXJlKSwKICAgIHNpemUgPSAzCiAgKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19mZXZlcl9tb250aCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjIGxpbWl0cyA9IGMoMCwgMC41KQogICkgKwogIGxhYnMoCiAgICB5ID0gIkFnZSIsCiAgICB4ID0gIlNlcm9wb3NpdGl2aXR5IiwKICAgIHRpdGxlID0gc3RyX3dyYXAoIk1hbGFyaWEgc2Vyb3Bvc2l0aXZpdHkgYnkgdGltZSBvZiBwbGFzbW9kaXVtIGFuZCBwcmVzZW5jZSBvZiBmZXZlciBpbiB0aGUgbGFzdCBtb250aCIsIDEwMCkKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDE2X3Nlcm9fdGltZW9mbWFsYXJpYV9mZXZlcm1vbnRoLnBuZyIsCiAgc2Vyb190aW1lb2ZtYWxhcmlhX2ZldmVyX21vbnRoLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCgojIyBSZWxhdGlvbiB3aXRoIEFudGltYWxhcmlhbCBEcnVncwoKIyMjIEJ5IDQgTWFsYXJpYQoKYGBge3J9CnNlcm9fNG1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICI0bWFsYXJpYSIsCiAgYWdlX2NhdCwKICBmZmlfaXNfYW50aW1hbF9kcnVnX3VzZQopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgY29sb3IgPSBtYWxhcmlhLAogICAgICBncm91cCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfYW50aW1hbF9kcnVnX3VzZSksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgbGltaXRzID0gYygwLCAwLjUwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X2FudGltYWxkcnVncwpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDE5X3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzLnBuZyIsCiAgc2Vyb180bWFsYXJpYV9kaXN0cmljdF9hbnRpbWFsZHJ1Z3MsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFR5cGUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9hbnRpbWFsZHJ1Z3MgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInR5cGVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX2FudGltYWxfZHJ1Z191c2UKKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfZ3JpZCgKICAgIHZhcnMoZmZpX2lzX2FudGltYWxfZHJ1Z191c2UpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC42MCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2FudGltYWxkcnVncwpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDIwX3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9hbnRpbWFsZHJ1Z3MucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0aW1lb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGZmaV9pc19hbnRpbWFsX2RydWdfdXNlCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgY29sb3IgPSBleHBvc3VyZSwKICAgICAgZ3JvdXAgPSBleHBvc3VyZQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGZmaV9pc19hbnRpbWFsX2RydWdfdXNlKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICBsaW1pdHMgPSBjKDAsIDAuNSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2FudGltYWxkcnVncwpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDIxX3Nlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9hbnRpbWFsZHJ1Z3MucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCgojIyBSZWxhdGlvbiB3aXRoIHRpbWUgb2Ygc29tZW9uZSBoYWQgbWFsYXJpYQoKIyMjIEJ5IGdlbmVyYWwgbWFsYXJpYQoKYGBge3J9CmZmaV80bWFsYXJpYV9tYWxfbGlmZXRpbWUgPC0gZmZpX3RvdGFsICU+JSAKICBkcm9wX25hKG9ubHlfcHZfZXhwb3N1cmU6ZnJlZWRvbV9tYWxhcmlhLCAKICAgICAgICAgIGFnZV9jb2RlLCBmZmlfaXNfbWFsX2xpZmV0aW1lKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKAogICAgY29scyA9IG9ubHlfcHZfZXhwb3N1cmU6ZnJlZWRvbV9tYWxhcmlhLAogICAgbmFtZXNfdG8gPSAibWFsYXJpYSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X21hbGFyaWEiCiAgKSAlPiUgCiAgbXV0YXRlKAogICAgcmVzdWx0X21hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIHJlc3VsdF9tYWxhcmlhID09ICJQb3NpdGl2ZSIgfiAxLAogICAgICBUUlVFIH4gMAogICAgKSwKICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIG1hbGFyaWEgPT0gIm9ubHlfcHZfZXhwb3N1cmUiIH4gIk9ubHkgUC4gdml2YXgiLAogICAgICBtYWxhcmlhID09ICJvbmx5X3BmX2V4cG9zdXJlIiB+ICJPbmx5IFAuIGZhbGNpcGFydW0iLAogICAgICBtYWxhcmlhID09ICJwdl9wZl9leHBvc3VyZSIgfiAiUC4gdml2YXggJiBmYWxjaXBhcnVtIEV4cG9zdXJlIiwKICAgICAgbWFsYXJpYSA9PSAiZnJlZWRvbV9tYWxhcmlhIiB+ICJGcmVlZG9tIGZyb20gTWFsYXJpYSIKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMoZmZpX2lzX2NvbW11bml0eTpmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUpLAogICAgICBzdHJfdG9fdGl0bGUKICAgICkKICApICU+JQogIGdyb3VwX2J5KGZmaV9pc19tYWxfbGlmZXRpbWUsIGFnZV9jb2RlLCBtYWxhcmlhKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X21hbGFyaWEgPSBtZWFuKHJlc3VsdF9tYWxhcmlhKSkKCnNlcm9fNG1hbGFyaWFfbWFsX2xpZmV0aW1lIDwtIGZmaV80bWFsYXJpYV9tYWxfbGlmZXRpbWUgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NvZGUsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgZmlsbCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX2FyZWEoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKAogICAgbGltaXRzID0gYygxLCA4KSwKICAgIGJyZWFrcyA9IHNlcSgxLCA4LCAxKSwKICAgIGxhYmVscyA9IGMoCiAgICAgICJbMC0xMCkiLAogICAgICAiWzEwLTIwKSIsCiAgICAgICJbMjAtMzApIiwKICAgICAgIlszMC00MCkiLAogICAgICAiWzQwLTUwKSIsCiAgICAgICJbNTAtNjApIiwKICAgICAgIls2MC03MCkiLAogICAgICAiWzcwKykiCiAgICApLAogICAgZXhwYW5kID0gYygwLCAwKQogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGV4cGFuZCA9IGMoMCwgMCkKICApICsKICBmYWNldF93cmFwKHZhcnMoZmZpX2lzX21hbF9saWZldGltZSkpICsKICBsYWJzKAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIsCiAgICB4ID0gIkFnZSIsCiAgICB0aXRsZSA9IHN0cl93cmFwKCJNYWxhcmlhIHNlcm9wb3NpdGl2aXR5IGJ5IHR5cGUgb2YgZXhwb3N1cmUsIHBsYXNtb2RpdW0gYW5kIGhvdyBtYW55IHRpbWVzIHRoZXkgdGhpbmsgdGhleSBoYXZlIGhhZCBtYWxhcmlhIiwgMTAwKQogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCgKICAgICAgYW5nbGUgPSA0NSwKICAgICAgdmp1c3QgPSAxLAogICAgICBoanVzdCA9IDEKICAgICksCiAgICBwYW5lbC5zcGFjaW5nID0gdW5pdCgxLCAibGluZXMiKQogICkKCnNlcm9fNG1hbGFyaWFfbWFsX2xpZmV0aW1lCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MjJfc2Vyb180b2ZtYWxhcmlhX21hbF9saWZldGltZS5wbmciLAogIHNlcm9fNG1hbGFyaWFfbWFsX2xpZmV0aW1lLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMSwKICBoZWlnaHQgPSA1CikKYGBgCgojIyMgQnkgUmVjZW50IE1hbGFyaWEKCmBgYHtyfQpmZmlfcmVjZW50bWFsYXJpYV9tYWxfbGlmZXRpbWUgPC0gZmZpX3RvdGFsICU+JSAKICBkcm9wX25hKG9ubHlfcHZfcmVjZW50OmZyZWVkb21fbWFsYXJpYV9yZWNlbnQsIAogICAgICAgICAgYWdlX2NvZGUsIGZmaV9pc19tYWxfbGlmZXRpbWUpICU+JSAKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gb25seV9wdl9yZWNlbnQ6ZnJlZWRvbV9tYWxhcmlhX3JlY2VudCwKICAgIG5hbWVzX3RvID0gIm1hbGFyaWEiLAogICAgdmFsdWVzX3RvID0gInJlc3VsdF9tYWxhcmlhIgogICkgJT4lIAogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJvbmx5X3B2X3JlY2VudCIgfiAiT25seSBQLiB2aXZheCBSZWNlbnQiLAogICAgICBtYWxhcmlhID09ICJvbmx5X3BmX3JlY2VudCIgfiAiT25seSBQLiBmYWxjaXBhcnVtIFJlY2VudCIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3BmX3JlY2VudCIgfiAiUC4gdml2YXggJiBmYWxjaXBhcnVtIFJlY2VudCIsCiAgICAgIG1hbGFyaWEgPT0gImZyZWVkb21fbWFsYXJpYV9yZWNlbnQiIH4gIkZyZWVkb20gZnJvbSBNYWxhcmlhIFJlY2VudCIKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMoZmZpX2lzX2NvbW11bml0eTpmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUpLAogICAgICBzdHJfdG9fdGl0bGUKICAgICkKICApICU+JQogIGdyb3VwX2J5KGZmaV9pc19tYWxfbGlmZXRpbWUsIGFnZV9jb2RlLCBtYWxhcmlhKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X21hbGFyaWEgPSBtZWFuKHJlc3VsdF9tYWxhcmlhKSkKCnNlcm9fcmVjZW50bWFsYXJpYV9tYWxfbGlmZXRpbWUgPC0gZmZpX3JlY2VudG1hbGFyaWFfbWFsX2xpZmV0aW1lICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jb2RlLAogICAgICB5ID0gcmVzdWx0X21hbGFyaWEsCiAgICAgIGZpbGwgPSBtYWxhcmlhCiAgICApCiAgKSArCiAgZ2VvbV9hcmVhKCkgKwogIHNjYWxlX3hfY29udGludW91cygKICAgIGxpbWl0cyA9IGMoMSwgOCksCiAgICBicmVha3MgPSBzZXEoMSwgOCwgMSksCiAgICBsYWJlbHMgPSBjKAogICAgICAiWzAtMTApIiwKICAgICAgIlsxMC0yMCkiLAogICAgICAiWzIwLTMwKSIsCiAgICAgICJbMzAtNDApIiwKICAgICAgIls0MC01MCkiLAogICAgICAiWzUwLTYwKSIsCiAgICAgICJbNjAtNzApIiwKICAgICAgIls3MCspIgogICAgKSwKICAgIGV4cGFuZCA9IGMoMCwgMCkKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICBleHBhbmQgPSBjKDAsIDApCiAgKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19tYWxfbGlmZXRpbWUpKSArCiAgbGFicygKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiLAogICAgeCA9ICJBZ2UiLAogICAgdGl0bGUgPSBzdHJfd3JhcCgiTWFsYXJpYSBzZXJvcG9zaXRpdml0eSBieSByZWNlbnQgZXhwb3N1cmUgYW5kIGhvdyBtYW55IHRpbWVzIHRoZXkgdGhpbmsgdGhleSBoYXZlIGhhZCBtYWxhcmlhIiwgMTAwKQogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCgKICAgICAgYW5nbGUgPSA0NSwKICAgICAgdmp1c3QgPSAxLAogICAgICBoanVzdCA9IDEKICAgICksCiAgICBwYW5lbC5zcGFjaW5nID0gdW5pdCgxLCAibGluZXMiKQogICkKCnNlcm9fcmVjZW50bWFsYXJpYV9tYWxfbGlmZXRpbWUKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QyM19zZXJvX3JlY2VudF9tYWxhcmlhX21hbF9saWZldGltZS5wbmciLAogIHNlcm9fcmVjZW50bWFsYXJpYV9tYWxfbGlmZXRpbWUsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDExLAogIGhlaWdodCA9IDUKKQpgYGAKCgojIyMgQnkgSGlzdG9yaWMgTWFsYXJpYQoKYGBge3J9CmZmaV9oaXN0b3JpY21hbGFyaWFfbWFsX2xpZmV0aW1lIDwtIGZmaV90b3RhbCAlPiUgCiAgZHJvcF9uYShvbmx5X3B2X2hpc3RvcmljOmZyZWVkb21fbWFsYXJpYV9oaXN0b3JpYywgCiAgICAgICAgICBhZ2VfY29kZSwgZmZpX2lzX21hbF9saWZldGltZSkgJT4lIAogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBvbmx5X3B2X2hpc3RvcmljOmZyZWVkb21fbWFsYXJpYV9oaXN0b3JpYywKICAgIG5hbWVzX3RvID0gIm1hbGFyaWEiLAogICAgdmFsdWVzX3RvID0gInJlc3VsdF9tYWxhcmlhIgogICkgJT4lIAogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJvbmx5X3B2X2hpc3RvcmljIiB+ICJPbmx5IFAuIHZpdmF4IEhpc3RvcmljIiwKICAgICAgbWFsYXJpYSA9PSAib25seV9wZl9oaXN0b3JpYyIgfiAiT25seSBQLiBmYWxjaXBhcnVtIEhpc3RvcmljIiwKICAgICAgbWFsYXJpYSA9PSAicHZfcGZfaGlzdG9yaWMiIH4gIlAuIHZpdmF4ICYgZmFsY2lwYXJ1bSBIaXN0b3JpYyIsCiAgICAgIG1hbGFyaWEgPT0gImZyZWVkb21fbWFsYXJpYV9oaXN0b3JpYyIgfiAiRnJlZWRvbSBmcm9tIE1hbGFyaWEgSGlzdG9yaWMiCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKSAlPiUKICBncm91cF9ieShmZmlfaXNfbWFsX2xpZmV0aW1lLCBhZ2VfY29kZSwgbWFsYXJpYSkgJT4lCiAgc3VtbWFyaXNlKHJlc3VsdF9tYWxhcmlhID0gbWVhbihyZXN1bHRfbWFsYXJpYSkpCgpzZXJvX2hpc3RvcmljbWFsYXJpYV9tYWxfbGlmZXRpbWUgPC0gZmZpX2hpc3RvcmljbWFsYXJpYV9tYWxfbGlmZXRpbWUgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NvZGUsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgZmlsbCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX2FyZWEoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKAogICAgbGltaXRzID0gYygxLCA4KSwKICAgIGJyZWFrcyA9IHNlcSgxLCA4LCAxKSwKICAgIGxhYmVscyA9IGMoCiAgICAgICJbMC0xMCkiLAogICAgICAiWzEwLTIwKSIsCiAgICAgICJbMjAtMzApIiwKICAgICAgIlszMC00MCkiLAogICAgICAiWzQwLTUwKSIsCiAgICAgICJbNTAtNjApIiwKICAgICAgIls2MC03MCkiLAogICAgICAiWzcwKykiCiAgICApLAogICAgZXhwYW5kID0gYygwLCAwKQogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGV4cGFuZCA9IGMoMCwgMCkKICApICsKICBmYWNldF93cmFwKHZhcnMoZmZpX2lzX21hbF9saWZldGltZSkpICsKICBsYWJzKAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIsCiAgICB4ID0gIkFnZSIsCiAgICB0aXRsZSA9IHN0cl93cmFwKCJNYWxhcmlhIHNlcm9wb3NpdGl2aXR5IGJ5IGhpc3RvcmljIGV4cG9zdXJlIGFuZCBob3cgbWFueSB0aW1lcyB0aGV5IHRoaW5rIHRoZXkgaGF2ZSBoYWQgbWFsYXJpYSIsIDEwMCkKICApICsKICBndWlkZXMoCiAgICBmaWxsID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9maWxsX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoCiAgICAgIGFuZ2xlID0gNDUsCiAgICAgIHZqdXN0ID0gMSwKICAgICAgaGp1c3QgPSAxCiAgICApLAogICAgcGFuZWwuc3BhY2luZyA9IHVuaXQoMSwgImxpbmVzIikKICApCgpzZXJvX2hpc3RvcmljbWFsYXJpYV9tYWxfbGlmZXRpbWUKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QyNF9zZXJvX2hpc3RvcmljX21hbGFyaWFfbWFsX2xpZmV0aW1lLnBuZyIsCiAgc2Vyb19oaXN0b3JpY21hbGFyaWFfbWFsX2xpZmV0aW1lLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMSwKICBoZWlnaHQgPSA1CikKYGBgCgoKIyMgUmVsYXRpb24gd2hlcmUgc29tZW9uZSB1c3VhbGx5IGJhdGhlCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGU8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAiNG1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX3BsYWNlX3Nob3dlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgY29sb3IgPSBtYWxhcmlhLAogICAgICBncm91cCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfcGxhY2Vfc2hvd2VyKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjUwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X3Vzc3VhbHliYXRoZQpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDI1X3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3RfdXNzdWFseWJhdGhlLnBuZyIsCiAgc2Vyb180bWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFR5cGUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInR5cGVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX3BsYWNlX3Nob3dlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfcGxhY2Vfc2hvd2VyKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjYwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfdXNzdWFseWJhdGhlCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MjZfc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X3Vzc3VhbHliYXRoZS5wbmciLAogIHNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFRpbWUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInRpbWVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX3BsYWNlX3Nob3dlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfcGxhY2Vfc2hvd2VyKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjUpCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKCnNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QyN19zZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfdXNzdWFseWJhdGhlLnBuZyIsCiAgc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X3Vzc3VhbHliYXRoZSwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTIsCiAgaGVpZ2h0ID0gOC41CikKYGBgCgoKIyMgUmVsYXRpb24gd2l0aCB0aG9zZSB3aG8gaGF2ZSBhIG1vc3F1aXRvIG5ldAoKIyMjIEJ5IDQgTWFsYXJpYQoKYGBge3J9CnNlcm9fNG1hbGFyaWFfZGlzdHJpY3RfbW9zcXVpdG5ldCA8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAiNG1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX21vc3FfbmV0CikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9tYWxhcmlhLAogICAgICBjb2xvciA9IG1hbGFyaWEsCiAgICAgIGdyb3VwID0gbWFsYXJpYQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGZmaV9pc19tb3NxX25ldCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC41MCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb180bWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0CmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90Mjhfc2Vyb180bWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0LnBuZyIsCiAgc2Vyb180bWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0LAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUeXBlIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfbW9zcXVpdG5ldCA8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAidHlwZW9mbWFsYXJpYSIsCiAgYWdlX2NhdCwKICBmZmlfaXNfbW9zcV9uZXQKKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfZ3JpZCgKICAgIHZhcnMoZmZpX2lzX21vc3FfbmV0KSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjYwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfbW9zcXVpdG5ldApgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDI5X3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0LnBuZyIsCiAgc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X21vc3F1aXRuZXQsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFRpbWUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0IDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0aW1lb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGZmaV9pc19tb3NxX25ldAopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfbW9zcV9uZXQpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgICNsaW1pdHMgPSBjKDAsIDAuNSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X21vc3F1aXRuZXQKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QzMF9zZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfbW9zcXVpdG5ldC5wbmciLAogIHNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0LAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIFJlbGF0aW9uIHdpdGggdGhvc2Ugd2hvIGhhdmUgYSB0cmlwIGluIHRoZSBsYXN0IG1vbnRoCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGggPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgIjRtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGZmaV9pc190cmlwX21vbnRoCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9tYWxhcmlhLAogICAgICBjb2xvciA9IG1hbGFyaWEsCiAgICAgIGdyb3VwID0gbWFsYXJpYQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGZmaV9pc190cmlwX21vbnRoKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjUwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X3RyaXBtb250aApgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDMxX3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3RfdHJpcG1vbnRoLnBuZyIsCiAgc2Vyb180bWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGgsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFR5cGUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGggPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInR5cGVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX3RyaXBfbW9udGgKKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfZ3JpZCgKICAgIHZhcnMoZmZpX2lzX3RyaXBfbW9udGgpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgICNsaW1pdHMgPSBjKDAsIDAuNjApCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKCnNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGgKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QzMl9zZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfdHJpcG1vbnRoLnBuZyIsCiAgc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X3RyaXBtb250aCwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTIsCiAgaGVpZ2h0ID0gOC41CikKYGBgCgojIyMgQnkgVGltZSBvZiBNYWxhcmlhCgpgYGB7cn0Kc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X3RyaXBtb250aCA8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAidGltZW9mbWFsYXJpYSIsCiAgYWdlX2NhdCwKICBmZmlfaXNfdHJpcF9tb250aAopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfdHJpcF9tb250aCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC41KQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfdHJpcG1vbnRoCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MzNfc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X3RyaXBtb250aC5wbmciLAogIHNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGgsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyBEZXNjcmlwdGl2ZSAwMV9kYXRhCgpgYGB7ciBldmFsPUZBTFNFfQpwbG90XzRfMiA8LSBmZmlfdG90YWwgJT4lCiAgZmlsdGVyKGZmaV9pc19tYWxhcmlhICVpbiUgYygiTm8iLCAiWWVzIikpICU+JQogIGRyb3BfbmEoYWdlX2NhdCwgcHZfaGlzdG9yaWMpICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWFfZ2VuZGVyID0gcGFzdGUoZ2VuZGVyLCBmZmlfaXNfbWFsYXJpYSkKICApICU+JQogIGNvdW50KHB2X2hpc3RvcmljLCBhZ2VfY2F0LCBtYWxhcmlhX2dlbmRlcikgJT4lCiAgbXV0YXRlKFBlcmNlbnRhZ2UgPSBuIC8gc3VtKG4pKSAlPiUKICBtdXRhdGUoCiAgICBQZXJjZW50YWdlID0gY2FzZV93aGVuKAogICAgICBzdHJfZGV0ZWN0KG1hbGFyaWFfZ2VuZGVyLCAiRmVtYWxlIikgfiBQZXJjZW50YWdlICogLTEsCiAgICAgIFRSVUUgfiBQZXJjZW50YWdlCiAgICApCiAgKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgeSA9IGFnZV9jYXQsCiAgICB4ID0gUGVyY2VudGFnZSwKICAgIGZpbGwgPSBtYWxhcmlhX2dlbmRlcgogICkpICsKICBnZW9tX2NvbCgKICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2socmV2ZXJzZSA9IFRSVUUpLAogICAgY29sb3IgPSAiYmxhY2siCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIEdyb3VwIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiUG9wdWxhdGlvbiBzdHJ1Y3R1cmUgYnkgYWdlIGdyb3VwcywgZ2VuZGVyIGFuZCBtYWxhcmlhIHRyYW5zbWlzc2lvbiIKICApICsKICBmYWNldF93cmFwKHZhcnMocHZfaGlzdG9yaWMpKSArIAogIHNjYWxlX3hfY29udGludW91cygKICAgIGxpbWl0cyA9IGMoLTAuMjUsIDAuMjUpLAogICAgYnJlYWtzID0gc2VxKC0wLjI1LCAwLjI1LCAwLjA1KSwKICAgIGxhYmVscyA9IGMocGFzdGUwKHNlcSgyNSwgMCwgLTUpLCAiJSIpLCBwYXN0ZTAoc2VxKDUsIDI1LCA1KSwgIiUiKSkKICApICsKICAjIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSgKICAgIHR5cGUgPSBpbm5vdmFyOjppbm5vdmFfcGFsKCJucHIiKSg0KSwKICAgIGxpbWl0cyA9IGMoIk1hbGUgWWVzIiwgIk1hbGUgTm8iLCAiRmVtYWxlIE5vIiwgIkZlbWFsZSBZZXMiKQogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIkhhdmUgeW91IGV2ZXIgXG5oYWQgbWFsYXJpYT8iKQogICkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxNCwKICAgICAgaGp1c3QgPSAwLjUsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KAogICAgICBzaXplID0gMTIsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxMiwKICAgICAgZmFjZSA9ICJib2xkIgogICAgKSwKICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDUsIDE1LCA1LCAxNSkKICApCmBgYAoKIyBEZXNjcmlwdGl2ZSAwMV9kYXRhCgpgYGB7ciBldmFsPUZBTFNFfQpwbG90XzRfMiA8LSBmZmlfdG90YWwgJT4lCiAgZmlsdGVyKGZmaV9pc19tYWxhcmlhICVpbiUgYygiTm8iLCAiWWVzIikpICU+JQogIGRyb3BfbmEoYWdlX2NhdCwgcHZfaGlzdG9yaWMpICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWFfZ2VuZGVyID0gcGFzdGUoZ2VuZGVyLCBmZmlfaXNfbWFsYXJpYSkKICApICU+JQogIGNvdW50KHB2X2hpc3RvcmljLCBhZ2VfY2F0LCBtYWxhcmlhX2dlbmRlcikgJT4lCiAgbXV0YXRlKFBlcmNlbnRhZ2UgPSBuIC8gc3VtKG4pKSAlPiUKICBtdXRhdGUoCiAgICBQZXJjZW50YWdlID0gY2FzZV93aGVuKAogICAgICBzdHJfZGV0ZWN0KG1hbGFyaWFfZ2VuZGVyLCAiRmVtYWxlIikgfiBQZXJjZW50YWdlICogLTEsCiAgICAgIFRSVUUgfiBQZXJjZW50YWdlCiAgICApCiAgKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgeSA9IGFnZV9jYXQsCiAgICB4ID0gUGVyY2VudGFnZSwKICAgIGZpbGwgPSBtYWxhcmlhX2dlbmRlcgogICkpICsKICBnZW9tX2NvbCgKICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2socmV2ZXJzZSA9IFRSVUUpLAogICAgY29sb3IgPSAiYmxhY2siCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIEdyb3VwIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiUG9wdWxhdGlvbiBzdHJ1Y3R1cmUgYnkgYWdlIGdyb3VwcywgZ2VuZGVyIGFuZCBtYWxhcmlhIHRyYW5zbWlzc2lvbiIKICApICsKICBmYWNldF93cmFwKHZhcnMocHZfaGlzdG9yaWMpKSArIAogIHNjYWxlX3hfY29udGludW91cygKICAgIGxpbWl0cyA9IGMoLTAuMjUsIDAuMjUpLAogICAgYnJlYWtzID0gc2VxKC0wLjI1LCAwLjI1LCAwLjA1KSwKICAgIGxhYmVscyA9IGMocGFzdGUwKHNlcSgyNSwgMCwgLTUpLCAiJSIpLCBwYXN0ZTAoc2VxKDUsIDI1LCA1KSwgIiUiKSkKICApICsKICAjIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSgKICAgIHR5cGUgPSBpbm5vdmFyOjppbm5vdmFfcGFsKCJucHIiKSg0KSwKICAgIGxpbWl0cyA9IGMoIk1hbGUgWWVzIiwgIk1hbGUgTm8iLCAiRmVtYWxlIE5vIiwgIkZlbWFsZSBZZXMiKQogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIkhhdmUgeW91IGV2ZXIgXG5oYWQgbWFsYXJpYT8iKQogICkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxNCwKICAgICAgaGp1c3QgPSAwLjUsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KAogICAgICBzaXplID0gMTIsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxMiwKICAgICAgZmFjZSA9ICJib2xkIgogICAgKSwKICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDUsIDE1LCA1LCAxNSkKICApCmBgYAoKIyMgU2Fua2V5X3Nlcm9wb3NpdGl2ZQoKCmBgYHtyfQpsaWJyYXJ5KGdnc2Fua2V5KQoKZmZpX2Zvcm1hdF9zYW5rZXkgPC0gZmZpX3RvdGFsICU+JQogIG11dGF0ZSgKICAgIGZmaV9pc19hY2Nlc3NfbWFsYXJpYV95bl9oZiA9IGZhY3RvcigKICAgICAgZmZpX2lzX2FjY2Vzc19tYWxhcmlhX3luX2hmLAogICAgICBsYWJlbCA9IGMoIk5vIiwgIlllcyIpCiAgICApLAogICAgZmZpX2lzX21hbF9saWZldGltZSA9IGFzLmNoYXJhY3RlcihmZmlfaXNfbWFsX2xpZmV0aW1lKSwKICAgIGZmaV9pc19tYWxfbGlmZXRpbWUgPSByZXBsYWNlX25hKGZmaV9pc19tYWxfbGlmZXRpbWUsICIwIHRpbWVzIiksCiAgICBmZmlfaXNfbWFsX2xpZmV0aW1lID0gZmFjdG9yKAogICAgICBmZmlfaXNfbWFsX2xpZmV0aW1lLAogICAgICBsYWJlbHMgPSBjKAogICAgICAgICIwIHRpbWVzIiwKICAgICAgICAiMSB0byAzIHRpbWVzIiwKICAgICAgICAiMyB0byA3IHRpbWVzIiwKICAgICAgICAiTW9yZSB0aGFuIDcgdGltZXMiCiAgICAgICkKICAgICkKICApCgpzYW5rZXlfc2Vyb3Bvc2l0aXZlX2Fuc3cxIDwtIGZmaV9mb3JtYXRfc2Fua2V5ICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBjKHJlY2VudF9leHBvc3VyZSwgZmZpX2lzX21hbF9saWZldGltZSwgZmZpX2lzX2FjY2Vzc19tYWxhcmlhX3luX2hmKSwKICAgIG5hbWVzX3RvID0gIm1hbGFyaWFfYmVoYXZpb3IxIiwKICAgIHZhbHVlc190byA9ICJtYWxhcmlhX2Fuc3cxIgogICkgJT4lCiAgY291bnQobWFsYXJpYV9iZWhhdmlvcjEsIG1hbGFyaWFfYW5zdzEpICU+JQogIGdyb3VwX2J5KG1hbGFyaWFfYmVoYXZpb3IxKSAlPiUKICBtdXRhdGUoCiAgICBwZXJjZW50YWdlID0gc2NhbGVzOjpwZXJjZW50KAogICAgICBuIC8gc3VtKG4pLAogICAgICBhY2N1cmFjeSA9IDAuMQogICAgKQogICkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWFfYmVoYXZpb3IxID0gZmN0X3JlbGV2ZWwoCiAgICAgIG1hbGFyaWFfYmVoYXZpb3IxLAogICAgICAiZmZpX2lzX21hbF9saWZldGltZSIsCiAgICAgICJmZmlfaXNfYWNjZXNzX21hbGFyaWFfeW5faGYiLAogICAgICAicmVjZW50X2V4cG9zdXJlIgogICAgKSwKICAgIG1hbGFyaWFfcGVyY2VudDEgPSBwYXN0ZTAoCiAgICAgIG1hbGFyaWFfYW5zdzEsCiAgICAgIHBhc3RlMCgiXG4oIiwgcGVyY2VudGFnZSwgIikiKQogICAgKSwKICAgIG1hbGFyaWFfcGVyY2VudDEgPSBhc19mYWN0b3IobWFsYXJpYV9wZXJjZW50MSkKICApICU+JQogIHNlbGVjdChtYWxhcmlhX2JlaGF2aW9yMSwgbWFsYXJpYV9hbnN3MSwgbWFsYXJpYV9wZXJjZW50MSkKCgpzYW5rZXlfc2Vyb3Bvc2l0aXZlIDwtIGZmaV9mb3JtYXRfc2Fua2V5ICU+JQogIGRyb3BfbmEoZmZpX2lzX21hbF9saWZldGltZSwgCiAgZmZpX2lzX2FjY2Vzc19tYWxhcmlhX3luX2hmLAogIHJlY2VudF9leHBvc3VyZQogICkgJT4lCiAgbWFrZV9sb25nKAogICAgZmZpX2lzX21hbF9saWZldGltZSwKICAgIGZmaV9pc19hY2Nlc3NfbWFsYXJpYV95bl9oZiwgCiAgICByZWNlbnRfZXhwb3N1cmUKICApICU+JQogIGxlZnRfam9pbigKICAgIHNhbmtleV9zZXJvcG9zaXRpdmVfYW5zdzEsCiAgICAgIGJ5ID0gYygKICAgICAgICAieCIgPSAibWFsYXJpYV9iZWhhdmlvcjEiLAogICAgICAgICJub2RlIiA9ICJtYWxhcmlhX2Fuc3cxIgogICAgICApCiAgKSAlPiUKICBtdXRhdGUoCiAgICBub2RlID0gbWFsYXJpYV9wZXJjZW50MSwKICAgIG5vZGUgPSBmY3RfcmV2KG5vZGUpCiAgKSAlPiUKICBzZWxlY3QoLW1hbGFyaWFfcGVyY2VudDEpICU+JQogIGxlZnRfam9pbigKICAgIHNhbmtleV9zZXJvcG9zaXRpdmVfYW5zdzEsCiAgICBieSA9IGMoCiAgICAgICJuZXh0X3giID0gIm1hbGFyaWFfYmVoYXZpb3IxIiwKICAgICAgIm5leHRfbm9kZSIgPSAibWFsYXJpYV9hbnN3MSIKICAgICkKICApICU+JQogIG11dGF0ZShuZXh0X25vZGUgPSBtYWxhcmlhX3BlcmNlbnQxKSAlPiUKICBzZWxlY3QoLW1hbGFyaWFfcGVyY2VudDEpICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0geCwKICAgIG5leHRfeCA9IG5leHRfeCwKICAgIG5vZGUgPSBub2RlLAogICAgbmV4dF9ub2RlID0gbmV4dF9ub2RlLAogICAgZmlsbCA9IGZhY3Rvcihub2RlKSwKICAgIGxhYmVsID0gbm9kZQogICkpICsKICBnZW9tX3NhbmtleSgKICAgIGZsb3cuYWxwaGEgPSAuOCwKICAgIG5vZGUuY29sb3IgPSAiZ3JheTMwIgogICkgKwogIGdlb21fc2Fua2V5X2xhYmVsKHNpemUgPSA0LCBjb2xvciA9ICJ3aGl0ZSIsIGZpbGwgPSAiZ3JheTMwIikgKwogIHNjYWxlX3hfZGlzY3JldGUoCiAgICBsYWJlbHMgPSBzdHJfd3JhcCgKICAgICAgYygKICAgICAgICAiSG93IG1hbnkgdGltZXMgZG8geW91IHRoaW5rIHlvdSBoYXZlIGhhZCBtYWxhcmlhIGluIHlvdXIgbGlmZT8iLAogICAgICAgICJJZiB5b3UgaGFkIG1hbGFyaWEsIHdvdWxkIHlvdSBnbyB0byB0aGUgaGVhbHRoIGZhY2lsaXR5PyIsCiAgICAgICAgIlJlY2VudCBleHBvc3VyZSB0byBhbnkgdHlwZSBvZiBwbGFzbW9kaXVtIgogICAgICApLAogICAgICAzMAogICAgKQogICkgKwogIHRoZW1lX3NhbmtleShiYXNlX3NpemUgPSAxOCkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgbGFicygKICAgIHggPSBOVUxMLAogICAgdGl0bGUgPSAiQmVoYXZpb3VyIGFzc29jaWF0ZWQgd2l0aCByZWNlbnQgbWFsYXJpYSBleHBvc3VyZSIKICApICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksCiAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbig1LCA1LCA1LCA1KQogICkKCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKCIuLzAyX291dHB1dC9wbG90cy9wbG90MzRfc2Fua2V5X3Nlcm9wb3NpdGl2ZS5wbmciLAogICAgICAgc2Fua2V5X3Nlcm9wb3NpdGl2ZSwKICAgICAgIGhlaWdodCA9IDcsCiAgICAgICB3aWR0aCA9IDE0LAogICAgICAgZHBpID0gMzAwKQpgYGAKCiMjIFJlbGF0aW9uIGdlbmRlciBhbmQgb2N1cGF0aW9uCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF9nZW5kZXJfZWNvbm9taWMgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgIjRtYWxhcmlhIiwKICBlY29ub21pY19hY3Rpdml0aWVzLAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGVjb25vbWljX2FjdGl2aXRpZXMsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgY29sb3IgPSBtYWxhcmlhLAogICAgICBncm91cCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40MCkKICApICsKICBsYWJzKAogICAgeCA9ICJFY29ub21pYyBBY3Rpdml0aWVzIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoCiAgICAgIGFuZ2xlID0gNDUsCiAgICAgIHZqdXN0ID0gMSwKICAgICAgaGp1c3QgPSAxCiAgICApCiAgKQoKc2Vyb180bWFsYXJpYV9kaXN0cmljdF9nZW5kZXJfZWNvbm9taWMKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QzNV9zZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcl9lY29ub21pYy5wbmciLAogIHNlcm9fNG1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyX2Vjb25vbWljLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMSwKICBoZWlnaHQgPSA3LjUsCiAgc2NhbGUgPSAwLjkKKQpgYGAKCiMjIyBCeSBUeXBlIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0eXBlb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDExX3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9nZW5kZXIucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0aW1lb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDEyX3Nlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9nZW5kZXIucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCgojIE1hcHMKCmBgYHtyfQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KGxlYWZsZXQpCmBgYAoKYGBge3J9CmZmaV90b3RhbF9ncHMgPC0gZmZpX3RvdGFsICU+JQogIHNlbGVjdCgKICAgIGZmaV9pc19jb2RfY29tOmZmaV9pc19jb2RfaW5kLAogICAgcGZfcmVjZW50OnB2X2hpc3RvcmljLAogICAgcHZfZXhwb3N1cmU6aGlzdG9yaWNhbF9leHBvc3VyZQogICkgJT4lCiAgbGVmdF9qb2luKAogICAgZmZpX2hvdXNlaG9sZCAlPiUKICAgICAgc2VsZWN0KAogICAgICAgIGZmaV9oX2NvZGVfY29tbXVuaXR5OmZmaV9oX2NvZGVfaG91c2Vob2xkLAogICAgICAgIGZmaV9oX2NvbW11bml0eQogICAgICApLAogICAgYnkgPSBjKAogICAgICAiZmZpX2lzX2NvZF9jb20iID0gImZmaV9oX2NvZGVfY29tbXVuaXR5IiwKICAgICAgImZmaV9pc19jb2RfaG91c2Vob2xkIiA9ICJmZmlfaF9jb2RlX2hvdXNlaG9sZCIKICAgICkKICApIAoKZmZpX2hvdXNlaG9sZF9ncHMgPC0gZmZpX3RvdGFsX2dwcyAlPiUKICBzZWxlY3QoCiAgICBmZmlfaXNfY29kX2NvbTpmZmlfaXNfY29kX2hvdXNlaG9sZCwKICAgIGZmaV9oX2NvbW11bml0eSwKICAgIHJlY2VudF9leHBvc3VyZQogICkgJT4lCiAgbXV0YXRlKAogICAgcmVjZW50X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICByZWNlbnRfZXhwb3N1cmUgPT0gIlBvc2l0aXZlIiB+IDEsCiAgICAgIFRSVUUgfiAwCiAgICApCiAgKSAlPiUKICBncm91cF9ieSgKICAgIGFjcm9zcyhjKGZmaV9pc19jb2RfY29tOmZmaV9oX2NvbW11bml0eSkpCiAgKSAlPiUKICBzdW1tYXJpc2UoCiAgICByZWNlbnRfZXhwb3N1cmUgPSBtZWFuKHJlY2VudF9leHBvc3VyZSkKICApICU+JQogIHVuZ3JvdXAoKQogICMgbXV0YXRlKAogICMgICBjb2xvcl9tYXJrZXIgPSBjYXNlX3doZW4oCiAgIyAgICAgcmVjZW50X2V4cG9zdXJlID09IDAgfiAicmVkIiwKICAjICAgICBUUlVFIH4gImJsYWNrIgogICMgICApCiAgIyApCgpmZmlfaG91c2Vob2xkX2dwcyA8LSBmZmlfaG91c2Vob2xkX2dwcyAlPiUKICBsZWZ0X2pvaW4oCiAgICBmZmlfaG91c2Vob2xkICU+JQogICAgICBzZWxlY3QoCiAgICAgICAgZmZpX2hfY29kZV9jb21tdW5pdHk6ZmZpX2hfY29kZV9ob3VzZWhvbGQsCiAgICAgICAgZmZpX2hfZGlzdHJpY3QsCiAgICAgICAgZmZpX2dwc19sb25nLAogICAgICAgIGZmaV9ncHNfbGF0CiAgICAgICksCiAgICBieSA9IGMoCiAgICAgICJmZmlfaXNfY29kX2NvbSIgPSAiZmZpX2hfY29kZV9jb21tdW5pdHkiLAogICAgICAiZmZpX2lzX2NvZF9ob3VzZWhvbGQiID0gImZmaV9oX2NvZGVfaG91c2Vob2xkIgogICAgKQogICkgJT4lCiAgbXV0YXRlKAogICAgZmZpX2hfaG91c2Vob2xkX2lkID0gcGFzdGUwKGZmaV9pc19jb2RfY29tLCBmZmlfaXNfY29kX2hvdXNlaG9sZCksCiAgICBmZmlfaXNfY29kX2NvbV9sYWJlbCA9IHBhc3RlMCgKICAgICAgIkNvZDogIiwKICAgICAgZmZpX2lzX2NvZF9ob3VzZWhvbGQsCiAgICAgICIgLSAiLAogICAgICBzdHJfdG9fdGl0bGUoZmZpX2hfY29tbXVuaXR5KSwKICAgICAgIiAoIiwKICAgICAgc3RyX3RvX3RpdGxlKGZmaV9oX2Rpc3RyaWN0KSwKICAgICAgIikiCiAgICApCiAgKSAlPiUKICBzdF9hc19zZigKICAgIGNvb3JkcyA9IGMoImZmaV9ncHNfbG9uZyIsICJmZmlfZ3BzX2xhdCIpLAogICAgY3JzID0gNDMyNgogICkgCiAgCgogIAojIGNvbG9yc19wYWwgPC0gcmV2KGlubm92YXI6Ojppbm5vdmFfcGFsZXR0ZXNbWyJlY29tc3QiXV0pCiMgcGFsIDwtIGNvbG9yTnVtZXJpYygKIyAgIGNvbG9yUmFtcChjb2xvcnNfcGFsKSwKIyAgIGZmaV9ob3VzZWhvbGRfZ3BzJHJlY2VudF9leHBvc3VyZQojICkKCnBhbCA8LSBjb2xvck51bWVyaWMoCiAgaGNsLmNvbG9ycygxNywgcGFsZXR0ZSA9ICJ6aXNzb3UiKSwKICBmZmlfaG91c2Vob2xkX2dwcyRyZWNlbnRfZXhwb3N1cmUKKQoKIyBpY29uc19ob3VzZWhvbGQgPC0gYXdlc29tZUljb25zKAojICAgaWNvbiA9ICJpb3MtaG9tZSIsCiMgICBpY29uQ29sb3IgPSAiYmxhY2siLAojICAgbGlicmFyeSA9ICJpb24iLAojICAgbWFya2VyQ29sb3IgPSBpbm5vdmFyOjppbm5vdmFfcGFsKCJlY29tc3QiLCByZXZlcnNlID0gVFJVRSkoMTcpCiMgKQoKY29tbXVuaXRpZXNfc2YgPC0gY29tbXVuaXRpZXNfc2YgJT4lCiAgbXV0YXRlKAogICAgZmZpX2hfY29tbXVuaXR5ID0gc3RyX3RvX3RpdGxlKGZmaV9oX2NvbW11bml0eSkKICApICU+JQogIGxlZnRfam9pbigKICAgIGZmaV9ob3VzZWhvbGQgJT4lCiAgICAgIHNlbGVjdChmZmlfaF9kaXN0cmljdCwgZmZpX2hfY29kZV9jb21tdW5pdHkpICU+JQogICAgICBkaXN0aW5jdCgpCiAgKSAgJT4lCiAgbXV0YXRlKAogICAgZmZpX2hfY29tbXVuaXR5X2xhYmVsID0gcGFzdGUwKAogICAgICBmZmlfaF9jb21tdW5pdHksCiAgICAgICIgKCIsCiAgICAgIHN0cl90b190aXRsZShmZmlfaF9kaXN0cmljdCksCiAgICAgICIpIgogICAgKQogICkKCgoKaG91c2Vob2xkX2NvbW11bml0aWVzX2xlYWZ0IDwtIGZmaV9ob3VzZWhvbGRfZ3BzICU+JQogIGxlYWZsZXQoKSAlPiUKICBhZGRQcm92aWRlclRpbGVzKAogICAgcHJvdmlkZXJzJE9wZW5TdHJlZXRNYXAsCiAgICBncm91cCA9ICJPcGVuU3RyZWV0TWFwIgogICkgJT4lCiAgYWRkQ2lyY2xlTWFya2VycygKICAgIGxheWVySWQgPSB+ZmZpX2hfaG91c2Vob2xkX2lkLAogICAgbGFiZWwgPSB+ZmZpX2lzX2NvZF9jb21fbGFiZWwsCiAgICBjb2xvciA9IH4gcGFsKHJlY2VudF9leHBvc3VyZSksCiAgICBncm91cCA9ICJIb3VzZWhvbGRzIiwKICAgIHJhZGl1cyA9IDcsCiAgICB3ZWlnaHQgPSA1LAogICAgb3BhY2l0eSA9IDEsCiAgICBmaWxsT3BhY2l0eSA9IDAuMSwKICAgIGxhYmVsT3B0aW9ucyA9IGxhYmVsT3B0aW9ucygKICAgICAgc3R5bGUgPSBsaXN0KAogICAgICAgICJmb250LXdlaWdodCIgPSAiYm9sZCIsCiAgICAgICAgcGFkZGluZyA9ICIzcHggOHB4IgogICAgICApLAogICAgICB0ZXh0c2l6ZSA9ICIxMnB4IiwKICAgICAgZGlyZWN0aW9uID0gImF1dG8iCiAgICApCiAgKSAlPiUKICAjIGFkZExlZ2VuZCgKICAjICAgdGl0bGUgPSAiUmVjZW50IEV4cG9zdXJlIiwKICAjICAgcGFsID0gcGFsLCAKICAjICAgdmFsdWVzID0gfiByZWNlbnRfZXhwb3N1cmUsIAogICMgICBncm91cCA9ICJjaXJjbGVzIiwgCiAgIyAgIHBvc2l0aW9uID0gImJvdHRvbWxlZnQiLAogICMgICB0cmFuc2Zvcm0gPSB+IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAjICAgb3BhY2l0eSA9IDEKICAjICkgJT4lPGZvbnQtYXdlc29tZS1pY29uIGljb249ImZhLXNvbGlkIGZhLWxvY2F0aW9uLWRvdCIgLz4KICBsZWFmbGVnZW5kOjphZGRMZWdlbmROdW1lcmljKAogICAgdGl0bGUgPSAiUmVjZW50IEV4cG9zdXJlIiwKICAgIHBhbCA9IHBhbCwKICAgIHZhbHVlcyA9IH4gcmVjZW50X2V4cG9zdXJlLAogICAgcG9zaXRpb24gPSAiYm90dG9tcmlnaHQiLAogICAgb3JpZW50YXRpb24gPSAiaG9yaXpvbnRhbCIsCiAgICBoZWlnaHQgPSAyMCwKICAgIHdpZHRoID0gMTAwLAogICAgZGVjcmVhc2luZyA9IEZBTFNFLAogICAgbnVtYmVyRm9ybWF0ID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgZ3JvdXAgPSAiY2lyY2xlcyIKICApICAlPiUKICBhZGRBd2Vzb21lTWFya2VycygKICAgIGRhdGEgPSBjb21tdW5pdGllc19zZiwKICAgIGxheWVySWQgPSB+ZmZpX2hfY29kZV9jb21tdW5pdHksCiAgICBsYWJlbCA9IH5mZmlfaF9jb21tdW5pdHlfbGFiZWwsCiAgICBncm91cCA9ICJDb21tdW5pdGllcyIKICApICU+JQogIGFkZFByb3ZpZGVyVGlsZXMoCiAgICBwcm92aWRlcnMkT3BlblN0cmVldE1hcCwKICAgIGdyb3VwID0gIk9wZW5TdHJlZXRNYXAiCiAgKSAlPiUKICBhZGRUaWxlcygKICAgIHVybFRlbXBsYXRlID0gImh0dHA6Ly9tdDAuZ29vZ2xlLmNvbS92dC9seXJzPW0maGw9ZW4meD17eH0meT17eX0mej17en0mcz1HYSIsCiAgICBhdHRyaWJ1dGlvbiA9ICJHb29nbGUgTWFwcyIsCiAgICBvcHRpb25zID0gbGVhZmxldDo6dGlsZU9wdGlvbnMoCiAgICAgIG1heE5hdGl2ZVpvb20gPSAxOSwKICAgICAgbWF4Wm9vbSA9IDIwCiAgICApLAogICAgZ3JvdXAgPSAiR29vZ2xlIE1hcHMiCiAgKSAlPiUKICBhZGRUaWxlcygKICAgIHVybFRlbXBsYXRlID0gImh0dHBzOi8vbXQxLmdvb2dsZS5jb20vdnQvbHlycz1zJng9e3h9Jnk9e3l9Jno9e3p9IiwKICAgIGF0dHJpYnV0aW9uID0gIlNhdGVsbGl0ZSBWaWV3IiwKICAgIG9wdGlvbnMgPSBsZWFmbGV0Ojp0aWxlT3B0aW9ucygKICAgICAgbWF4TmF0aXZlWm9vbSA9IDE5LAogICAgICBtYXhab29tID0gMjAKICAgICksCiAgICBncm91cCA9ICJTYXRlbGxpdGUgVmlldyIKICApICU+JQogICMgTGF5ZXJzIGNvbnRyb2wqCiAgYWRkTGF5ZXJzQ29udHJvbCgKICAgIG92ZXJsYXlHcm91cHMgPSBjKCJIb3VzZWhvbGRzIiwgIkNvbW11bml0aWVzIiksCiAgICBiYXNlR3JvdXBzID0gYygiT3BlblN0cmVldE1hcCIsICJHb29nbGUgTWFwcyIsICJTYXRlbGxpdGUgVmlldyIpLAogICAgb3B0aW9ucyA9IGxheWVyc0NvbnRyb2xPcHRpb25zKGNvbGxhcHNlZCA9IEZBTFNFKQogICkgJT4lCiAgIyBhZGRMZWdlbmQoCiAgIyAgICJ0b3ByaWdodCIsCiAgIyAgIHBhbCA9IGlubm92YXI6Omlubm92YV9wYWwoImVjb21zdCIsIHJldmVyc2UgPSBUUlVFKSg5ODApCiAgIyApICAlPiUKICAjIGFkZExlZ2VuZCgKICAjICAgcG9zaXRpb24gPSAiYm90dG9tcmlnaHQiLAogICMgICBjb2xvcnMgPSBjKAogICMgICAgICJ3aGl0ZTsgd2lkdGg6MTVweDsgaGVpZ2h0OjE1cHg7CiAgIyAgICAgICAgICAgICAgICBib3JkZXI6NXB4IHNvbGlkIHJlZDsgYm9yZGVyLXJhZGl1czo1MCU7IiwKICAjICAgICAid2hpdGU7IHdpZHRoOjcuNXB4OyBoZWlnaHQ6Ny41cHg7IG1hcmdpbi10b3A6IDVweDsKICAjICAgICAgICAgICAgICAgIGJvcmRlcjo1cHggc29saWQgYmxhY2s7IGJvcmRlci1yYWRpdXM6NTAlOyBtYXJnaW4tbGVmdDoycHg7IgogICMgICApLAogICMgICBsYWJlbHMgPSBjKAogICMgICAgICI8ZGl2IHN0eWxlPSdkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGhlaWdodDogMTBweDsKICAjICAgICAgICAgICAgICAgIG1hcmdpbi10b3A6IDhweDtsaW5lLWhlaWdodDogMTBweDtmb250LXdlaWdodDogYm9sZDsKICAjICAgICAgICAgICAgICAgIGNvbG9yOiBibGFjazsgJz5BdCBsZWFzdCAxIHBlcnNvbiB3aXRoIHJlY2VudCBtYWxhcmlhPC9kaXY+IiwKICAjICAgICAiPGRpdiBzdHlsZT0nZGlzcGxheTogaW5saW5lLWJsb2NrO2hlaWdodDogMTBweDsKICAjICAgICAgICAgICAgICAgIG1hcmdpbi10b3A6IDhweDtsaW5lLWhlaWdodDogMTBweDtmb250LXdlaWdodDogYm9sZDsKICAjICAgICAgICAgICAgICAgIGNvbG9yOiBibGFjazsgbWFyZ2luLXRvcDogMTBweDsKICAjICAgICAgICAgICAgICAgIG1hcmdpbi1sZWZ0OjVweCc+Tm8gb25lIHdpdGggcmVjZW50IG1hbGFyaWEgYXQgaG91c2Vob2xkPC9kaXY+IgogICMgICApLAogICMgICBvcGFjaXR5ID0gMQogICMgKSAlPiUKICBsZWFmbGV0LmV4dHJhczo6YWRkUmVzZXRNYXBCdXR0b24oKQpgYGAKCgpgYGB7ciBldmFsPUZBTFNFfQpodG1sd2lkZ2V0czo6c2F2ZVdpZGdldCgKICBob3VzZWhvbGRfY29tbXVuaXRpZXNfbGVhZnQsCiAgZmlsZSA9ICIuLzAyX291dHB1dC9wbG90cy9ob3VzZWhvbGRfY29tbXVuaXRpZXNfbGVhZnQuaHRtbCIKKQoKd2Vic2hvdDo6d2Vic2hvdCgKICAiLi8wMl9vdXRwdXQvcGxvdHMvaG91c2Vob2xkX2NvbW11bml0aWVzX2xlYWZ0Lmh0bWwiLAogICIuLzAyX291dHB1dC9wbG90cy9ob3VzZWhvbGRfY29tbXVuaXRpZXNfbGVhZnQucG5nIiwKICBjbGlwcmVjdCA9ICJ2aWV3cG9ydCIsCiAgem9vbSA9IDQKKQpgYGA=